简体   繁体   English

如何在Ruby中的哈希中初始化数组

[英]How can I initialize an Array inside a Hash in Ruby

I am trying to initialize a Hash of Arrays such as 我正在尝试初始化数组的哈希,例如

@my_hash = Hash.new(Array.new)

so that I can: 这样我可以:

@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"]

The problem is that any new hash key also return ["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"]

!!!??? !!! ???

What am I doing wrong what would be the correct way to initialize a Hash of Arrays? 我在做什么错,初始化数组哈希的正确方法是什么?

@my_hash = Hash.new(Array.new)

This creates exactly one array object, which is returned every time a key is not found. 这将创建一个数组对象,每次找不到键时将返回该数组对象。 Since you only ever mutate that array and never create a new one, all your keys map to the same array. 由于您只修改该数组而从未创建一个新数组,因此所有键都映射到同一数组。

What you want to do is: 您想要做的是:

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

or simply 或简单地

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

Passing a block to Hash.new differs from simply passing an argument in 2 ways: 将块传递给Hash.new不同于仅通过两种方式传递参数:

  1. The block is executed every time a key is not found. 每次找不到键时执行该块。 Thus you'll get a new array each time. 这样,您每次都会得到一个新的数组。 In the version with an argument, that argument is evaluated once (before new is called) and the result of that is returned every time. 在带有参数的版本中,该参数被评估一次(在调用new之前),并且每次都返回其结果。

  2. By doing h[k] = you actually insert the key into the hash. 通过执行h[k] =您实际上将密钥插入到哈希中。 If you don't do this just accessing @my_hash[some_key] won't actually cause some_key to be inserted in the hash. 如果你不这样做只是访问@my_hash[some_key]实际上不会造成some_key在哈希插入。

尝试这个:

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

The argument for Hash.new is for the default value for new hash keys, so when you pass it a reference that reference will be used for new hash keys. Hash.new的参数是新哈希键的默认值,因此当您传递它的引用时,该引用将用于新哈希键。 You're updating that reference when you call... 您在致电时正在更新该参考...

hash["key"].push "value"

You need to pass a new reference into the hash key before pushing values to it... 您需要在将值推入哈希键之前将新引用传递给哈希键...

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

You could try encapsulating this into a helper method as well. 您也可以尝试将其封装到一个辅助方法中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM