使用空数组意外行为初始化哈希

时间:2015-01-30 11:59:17

标签: ruby hash

我想初始化一个空Hash的{​​{1}},并且每个新键都会将某个值推送到该数组。

这是我试图做的事情:

Array

a = Hash.new([]) # => {} a[1] << "asd" # => ["asd"] a # => {} 的预期输出为a但未发生这种情况。我在这里缺少什么?

Ruby版本:

{1 => ["asd"]}

1 个答案:

答案 0 :(得分:9)

只做

a = Hash.new { |h, k| h[k] = [] }
a[1] << "asd"
a # => {1=>["asd"]}

阅读Hash::new文档中的以下行。这真的解释了为什么你没有得到理想的结果。

new(obj)→new_hash

  

如果指定了obj,则此单个对象将用于所有默认值。

new {| hash,key |阻止}→new_hash

  

如果指定了一个块,它将使用哈希对象和键调用,并应返回默认值。如果需要,该块负责将值存储在哈希值中。

您可以手动测试:

a = Hash.new([])
a[1].object_id # => 2160424560
a[2].object_id # => 2160424560

现在使用上述Hash对象创建方式,您可以看到对未知密钥的每次访问,并返回相同的默认对象。现在反过来,我的意思是阻止方式

b = Hash.new { |h, k| [] }
b[2].object_id # => 2168989980
b[1].object_id # => 2168933180

因此,使用表单,每个未知密钥访问,返回一个新的Array对象。