如何在Ruby中的Hash中初始化一个数组

时间:2010-12-10 14:57:38

标签: ruby arrays hash

我正在尝试初始化一个Hash of Arrays,例如

@my_hash = Hash.new(Array.new)

这样我就可以:

@my_hash["hello"].push("in the street")
=> ["in the street"]
@my_hash["hello"].push("at home")
=> ["in the street", "at home"]
@my_hash["hello"]
=>["in the street", "at home"]

问题是任何新的哈希键也会返回["in the street", "at home"]

@my_hash["bye"]
=> ["in the street", "at home"]
@my_hash["xxx"]
=> ["in the street", "at home"]

!!! ???

我做错了什么是初始化Hash of Arrays的正确方法?

3 个答案:

答案 0 :(得分:89)

@my_hash = Hash.new(Array.new)

这会创建一个数组对象,每次找不到键时都会返回该对象。由于您只是改变了该数组并且从不创建新数组,因此所有键都映射到同一个数组。

您想要做的是:

@my_hash = Hash.new {|h,k| h[k] = Array.new }

或只是

@my_hash = Hash.new {|h,k| h[k] = [] }

将块传递给Hash.new不同于简单地以两种方式传递参数:

  1. 每次找不到密钥时都会执行该块。因此,每次都会得到一个新数组。在带有参数的版本中,该参数被计算一次(在调用new之前)并且每次都返回该结果。

  2. 通过执行h[k] =,您实际将密钥插入哈希。如果您不这样做,只访问@my_hash[some_key]实际上不会导致some_key插入哈希值。

答案 1 :(得分:7)

试试这个:

@my_hash = Hash.new { |h, k| h[k] = Array.new }

答案 2 :(得分:2)

Hash.new的参数是新哈希键的默认值,因此当您传递引用时,该引用将用于新的哈希键。您在致电时正在更新该参考资料......

hash["key"].push "value"

在将值推送到它之前,您需要将新引用传递给哈希键...

hash["key1"] = Array.new
hash["key1"].push "value1"
hash["key2"] = Array.new
hash["key2"].push "value2

您也可以尝试将其封装到辅助方法中。