21

在 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)
4

3 回答 3

26

您可以使用以下方式分配默认值default=

d.default = 0

请注意,这不会真正自动激活,它只是在没有实际添加键d[:new_key]的情况下返回零。如果您打算修改默认值,也可能会导致问题;这意味着这几乎总是一个错误,因为在访问默认值时不会复制数组。:new_keydefault=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 }
于 2013-11-03T20:12:28.607 回答
18

您可以为此使用方法的第一个参数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 }
于 2013-11-03T20:08:21.780 回答
9

Hash的标准new方法接受一个块。如果尝试访问 Hash 中不存在的键,则会调用此块。该块被传递哈希本身和请求的键(两个参数),并且应该返回应该为请求的键返回的值。

这可用于创建自动生成的哈希,除其他外:

h = Hash.new{ |h,k| h[k] = 'default value'}
于 2013-11-03T20:30:47.467 回答