如果 hash['a'] 不存在,如何分配 hash['a']['b']='c'? [英] How to assign hash['a']['b']= 'c' if hash['a'] doesn't exist?
问题描述
有没有比
if hash.key?('a')
hash['a']['b'] = 'c'
else
hash['a'] = {}
hash['a']['b'] = 'c'
end
推荐答案
最简单的方法是 使用块参数构建您的哈希:
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
的这个表单创建一个新的空哈希作为默认值.你不想要这个:
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.
此外,正如 Phrogz 所指出的,您可以使用 default_proc
:
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:我想我应该澄清我对 Hash.new({ })
的警告.当你这样说时:
UPDATE: I think I should clarify my warning against Hash.new({ })
. When you say this:
h = Hash.new({ })
这很像这样说:
h = Hash.new
h.default = { }
然后,当您访问 h
以将某些内容分配为 h[:k][:m] = y
时,它的行为就好像您这样做了:>
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
然后,如果你h[:k2][:n] = z
,你最终会分配h.default[:n] = z
.请注意,h
仍然表示 h.has_key?(:k)
是假的.
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.
但是,当你这样说时:
h = Hash.new(0)
一切都会好起来的,因为你永远不会在这里修改 h[k]
,你只会从 h
读取一个值(它将使用默认的如有必要)或为 h
分配一个新值.
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
.
这篇关于如果 hash['a'] 不存在,如何分配 hash['a']['b']='c'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!