How to assign hash['a']['b']= 'c' if hash['a'] doesn't exist?

做~自己de王妃 提交于 2019-12-17 06:38:10

问题


Is there any way simpler than

if hash.key?('a')
  hash['a']['b'] = 'c' 
else  
  hash['a'] = {}
  hash['a']['b'] = 'c' 
end

回答1:


The easiest way is to construct your Hash with a block argument:

hash = Hash.new { |h, k| h[k] = { } }
hash['a']['b'] = 1
hash['a']['c'] = 1
hash['b']['c'] = 1
puts hash.inspect
# "{"a"=>{"b"=>1, "c"=>1}, "b"=>{"c"=>1}}"

This form for new creates a new empty Hash as the default value. You don't want this:

hash = Hash.new({ })

as that will use the exact same hash for all default entries.

Also, as Phrogz notes, you can make the auto-vivified hashes auto-vivify using default_proc:

hash = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }

UPDATE: I think I should clarify my warning against Hash.new({ }). When you say this:

h = Hash.new({ })

That's pretty much like saying this:

h = Hash.new
h.default = { }

And then, when you access h to assign something as h[:k][:m] = y, it behaves as though you did this:

if(h.has_key?(:k))
    h[:k][:m] = y
else
    h.default[:m] = y
end

And then, if you h[:k2][:n] = z, you'll end up assigning h.default[:n] = z. Note that h still says that h.has_key?(:k) is false.

However, when you say this:

h = Hash.new(0)

Everything will work out okay because you will never modified h[k] in place here, you'll only read a value from h (which will use the default if necessary) or assign a new value to h.




回答2:


a simple one, but hash should be a valid hash object

(hash["a"] ||= {})['b'] = "c"



回答3:


If you create hash as the following, with default value of a new (identically default-valued) hash: (thanks to Phrogz for the correction; I had the syntax wrong)

hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }

Then you can do

hash["a"]["b"] = "c"

without any additional code.




回答4:


The question here: Is auto-initialization of multi-dimensional hash array possible in Ruby, as it is in PHP? provides a very useful AutoHash implementation that does this.




回答5:


class NilClass
  def [](other)
    nil
  end
end

Once you defined that, everything will work automatically. But be aware that from now on nil would behave as an empty hash when used as a hash.



来源:https://stackoverflow.com/questions/5878529/how-to-assign-hashab-c-if-hasha-doesnt-exist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!