ruby用数组值添加到hash

Jef*_*rey 12 ruby hash

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

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

但是,如果我将其修改为

map = Hash.new
strings = ["abc","def","four","five"]
strings.each do |word|
  map[word.length] ||= []
  map[word.length] << word  
end
Run Code Online (Sandbox Code Playgroud)

它确实有效.

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

Ry-*_*Ry- 27

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

h = Hash.new []
p h[0]           # []
h[0] << "Hello"
p h              # {}
p h[0]           # ["Hello"]
p h[1]           # ["Hello"]
Run Code Online (Sandbox Code Playgroud)

这是因为相同的Array对象保持为默认值.您可以使用+运算符修复它,但效率可能较低:

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

strings.each do |word|
    map[word.length] += [word]
end
Run Code Online (Sandbox Code Playgroud)

现在它按预期工作.


tok*_*and 11

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

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