有什么比简单的方法吗
if hash.key?('a') hash['a']['b'] = 'c' else hash['a'] = {} hash['a']['b'] = 'c' end
解决方法
最简单的方法是
construct your Hash带块参数:
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}}"
这个新的表单创建一个新的空的哈希作为默认值.你不想这样:
hash = Hash.new({ })
因为这将为所有默认条目使用完全相同的哈希.
另外,正如Phrogz所说,您可以使用自动生成的哈希自动生成default_proc
:
hash = Hash.new { |h,k| h[k] = Hash.new(&h.default_proc) }
更新:我想我应该澄清我对Hash.new({})的警告.当你这样说:
h = Hash.new({ })
这很像这样说:
h = Hash.new h.default = { }
然后,当你访问h来分配一些东西作为h [:k] [:m] = y,它的行为就好像你这样做:
if(h.has_key?(:k)) h[:k][:m] = y else h.default[:m] = y end
然后,如果你[:k2] [:n] = z,你最终会分配h.default [:n] = z.请注意,h仍然说h.has_key?(:k)是假的.
但是,当你这样说:
h = Hash.new(0)
一切都会好起来的,因为你永远不会在这里修改h [k],你只会从h读取一个值(如果需要的话会使用默认值),或者为h分配一个新值.