ruby用数组值添加到hash

时间:2012-07-21 03:44:01

标签: ruby hash

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

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

但是,如果我将其修改为

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

确实有效。

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

3 个答案:

答案 0 :(得分:27)

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

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

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

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

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

现在它按预期工作。

答案 1 :(得分:11)

无论如何,您应该使用Enumerable#group_by

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

答案 2 :(得分:2)

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

这对于进一步clarify来说是一个很好的阅读。

相关问题