我正在尝试初始化一个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的正确方法?
答案 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
不同于简单地以两种方式传递参数:
每次找不到密钥时都会执行该块。因此,每次都会得到一个新数组。在带有参数的版本中,该参数被计算一次(在调用new
之前)并且每次都返回该结果。
通过执行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
您也可以尝试将其封装到辅助方法中。