如何在Ruby中的散列中初始化数组

时间:2021-03-24 22:30:27

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?

我做错了什么正确的初始化数组哈希的方法是什么?

3 个解决方案

#1


85  

@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:

传递一个块到散列。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.

    每次没有找到密钥时都会执行该块。因此,每次都将得到一个新的数组。在带有参数的版本中,该参数将在每次调用之前(在新调用之前)进行评估,并且每次都返回该参数的结果。

  2. By doing h[k] = you actually insert the key into the hash. If you don't do this just accessing @my_hash[some_key] won't actually cause some_key to be inserted in the hash.

    通过执行h[k] =,实际上是将键插入到散列中。如果不这样做,那么访问@my_hash[some_key]实际上不会导致将some_key插入到散列中。

#2


7  

Try this:

试试这个:

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

#3


2  

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. You're updating that reference when you call...

哈希的论点。new是用于新散列键的默认值,因此当您传递它时,引用将用于新的散列键。当你打电话给…

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.

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

#1


85  

@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:

传递一个块到散列。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.

    每次没有找到密钥时都会执行该块。因此,每次都将得到一个新的数组。在带有参数的版本中,该参数将在每次调用之前(在新调用之前)进行评估,并且每次都返回该参数的结果。

  2. By doing h[k] = you actually insert the key into the hash. If you don't do this just accessing @my_hash[some_key] won't actually cause some_key to be inserted in the hash.

    通过执行h[k] =,实际上是将键插入到散列中。如果不这样做,那么访问@my_hash[some_key]实际上不会导致将some_key插入到散列中。

#2


7  

Try this:

试试这个:

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

#3


2  

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. You're updating that reference when you call...

哈希的论点。new是用于新散列键的默认值,因此当您传递它时,引用将用于新的散列键。当你打电话给…

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.

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