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不同于简单地通过两种方式传递一个参数:
-
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.每次没有找到密钥时都会执行该块。因此,每次都将得到一个新的数组。在带有参数的版本中,该参数将在每次调用之前(在新调用之前)进行评估,并且每次都返回该参数的结果。
-
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 causesome_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不同于简单地通过两种方式传递一个参数:
-
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.每次没有找到密钥时都会执行该块。因此,每次都将得到一个新的数组。在带有参数的版本中,该参数将在每次调用之前(在新调用之前)进行评估,并且每次都返回该参数的结果。
-
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 causesome_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方法中。