在Python中,我可以创建一个哈希值,其中每个元素在首次引用时都具有默认值(也称为“autovivification”)。这是一个例子:
from collections import defaultdict
d = defaultdict(int)
d["new_key"] += 1
print d
打印dict显示“new_key”的值为1。
Ruby中的等价物是什么?此代码抛出错误:
d = {}
d[:new_key] += 1
puts d
test.rb:3:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)
答案 0 :(得分:22)
您可以使用default=
指定默认值:
d.default = 0
请注意,这不会真正自动生成,它只会使d[:new_key]
返回零而不实际添加:new_key
键。如果您打算修改默认值,default=
也会导致问题;这意味着d.default = [ ]
几乎总是一个错误,因为访问默认值时不会复制数组。
更好的选择通常是default_proc=
:
d.default_proc = proc { |h, k| h[k] = 0 }
这允许您拥有不同的默认值,并允许您添加新密钥(或不依赖于proc
的结构)。
您还可以在创建哈希时设置这些:
d = Hash.new(0)
d = Hash.new { |h, k| h[k] = 0 }
答案 1 :(得分:14)
您可以使用Hash.new
方法的第一个参数:
d = Hash.new 0
d[:new_key] += 1
d[:new_key] #=> 1
d[:foo] #=> 0
小心 - 您可能会意外更改默认值:
h = Hash.new("Go Fish")
h[:unknown_key] #=> "Go Fish"
h[:unknown_key].upcase! #=> "GO FISH"
h[:next_key] #=> "GO FISH"
由于答案中指出“mu太短”,你应该更好地使用proc,如:
h = Hash.new { |h, k| h[k] = 0 }
答案 2 :(得分:9)
Hash的标准new
方法接受一个块。如果尝试访问Hash中不存在的密钥,则调用此块。该块传递Hash本身和请求的密钥(两个参数),并应返回应为请求的密钥返回的值。
这可以用来创建一个自动生成的哈希,其中包括:
h = Hash.new{ |h,k| h[k] = 'default value'}