ruby 添加到带有数组值的哈希

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11589269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 05:18:48  来源:igfitidea点击:

ruby adding to hash with array value

rubyhash

提问by Jeff Storey

I tried the following ruby code, which I thought would return a hash of word lengths to the words with those lengths. Instead it is empty.

我尝试了以下 ruby​​ 代码,我认为它会将单词长度的散列返回到具有这些长度的单词。相反,它是空的。

map = Hash.new(Array.new)    
strings = ["abc","def","four","five"]
strings.each do |word|
  map[word.length] << word  
end   

However, if I modify it to

但是,如果我将其修改为

map = Hash.new
strings = ["abc","def","four","five"]
strings.each do |word|
  map[word.length] ||= []
  map[word.length] << word  
end

It does work.

它确实有效。

Doesn't the first version just create a hash whose default values are an empty array? In this case, I don't understand why the 2 blocks give different values.

第一个版本不只是创建一个默认值为空数组的哈希吗?在这种情况下,我不明白为什么 2 个块给出不同的值。

回答by Ry-

The problem is that you aren't actually assigning anything to the hash keys, you're just using the <<operator to modify the existing contents of a default value. Since you don't assign anything to the hash key, it is not added. In fact, you'll notice the default value is the one modified:

问题是您实际上并没有为散列键分配任何内容,您只是使用<<运算符来修改默认值的现有内容。由于您没有为散列键分配任何内容,因此不会添加任何内容。事实上,您会注意到默认值是修改后的值:

h = Hash.new []
p h[0]           # []
h[0] << "Hello"
p h              # {}
p h[0]           # ["Hello"]
p h[1]           # ["Hello"]

This is because the same Arrayobject is maintained as the default value. You can fix it by using the +operator, though it may be less efficient:

这是因为相同的Array对象被维护为默认值。您可以使用+运算符修复它,尽管它可能效率较低:

map = Hash.new []
strings = ["abc", "def", "four", "five"]

strings.each do |word|
    map[word.length] += [word]
end

And now it works as expected.

现在它按预期工作。

回答by tokland

In any case, you should use Enumerable#group_by:

在任何情况下,您都应该使用Enumerable#group_by

["abc", "def", "four", "five"].group_by(&:length)
#=> {3=>["abc", "def"], 4=>["four", "five"]}

回答by Benjamin Tan Wei Hao

I think what the first version really means is that the default value is only onearray. The second example explicitly creates a new array if one doesn't exist yet.

我认为第一个版本的真正含义是默认值只有一个数组。如果一个新数组尚不存在,第二个示例显式创建一个新数组。

This looks like a good read to further clarify.

这看起来像进一步澄清的好读物。