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

jfa*_*als 34 ruby arrays hash

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

@my_hash = Hash.new(Array.new)
Run Code Online (Sandbox Code Playgroud)

这样我就可以:

@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"]
Run Code Online (Sandbox Code Playgroud)

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

@my_hash["bye"]
=> ["in the street", "at home"]
@my_hash["xxx"]
=> ["in the street", "at home"]
Run Code Online (Sandbox Code Playgroud)

!!! ???

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

sep*_*p2k 90

@my_hash = Hash.new(Array.new)
Run Code Online (Sandbox Code Playgroud)

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

你想要做的是:

@my_hash = Hash.new {|h,k| h[k] = Array.new }
Run Code Online (Sandbox Code Playgroud)

或者干脆

@my_hash = Hash.new {|h,k| h[k] = [] }
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 需要注意的是,现在即使*检查*一个键也会创建它,这可能不是你想要的.出于这个原因,我有时会正常创建Hash(只有{}),然后在调用中进行数组创建,如`(@myhash ["hello"] || = []).push("在街上")`. (14认同)

Inc*_*tly 7

试试这个:

@my_hash = Hash.new { |h, k| h[k] = Array.new }
Run Code Online (Sandbox Code Playgroud)