有没有比
更简单的方法if hash.key?('a')
hash['a']['b'] = 'c'
else
hash['a'] = {}
hash['a']['b'] = 'c'
end
答案 0 :(得分:39)
最简单的方法是使用块参数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}}"
new
的此表单创建一个新的空哈希作为默认值。你不想要这个:
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
然后,如果您h[:k2][:n] = z
,您最终会分配h.default[:n] = z
。请注意,h
仍然表示h.has_key?(:k)
为假。
然而,当你这样说:
h = Hash.new(0)
一切都会好起来的,因为你永远不会在这里修改h[k]
,你只会从h
中读取一个值(必要时将使用默认值)或者为其分配一个新值h
。
答案 1 :(得分:10)
一个简单的,但哈希应该是一个有效的哈希对象
(hash["a"] ||= {})['b'] = "c"
答案 2 :(得分:2)
如果您创建hash
如下所示,默认值为新的(默认值相同)散列:(感谢Phrogz进行更正;我的语法错误)
hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }
然后你可以做
hash["a"]["b"] = "c"
没有任何额外的代码。
答案 3 :(得分:0)
这里的问题:
Is auto-initialization of multi-dimensional hash array possible in Ruby, as it is in PHP?
提供了一个非常有用的AutoHash
实现,可以做到这一点。
答案 4 :(得分:0)
class NilClass
def [](other)
nil
end
end
一旦你定义了,一切都会自动生效。但请注意,从现在开始nil
在用作哈希时会表现为空哈希。