我有一个像这样的数组
[1,1,2,3,3,3,4,5,5]
Run Code Online (Sandbox Code Playgroud)
我想计算每个数字的出现次数,我正试图这样做
[1,1,2,3,3,3,4,5,5].reduce(Hash.new(0)) { |hash,number| hash[number] += 1 }
Run Code Online (Sandbox Code Playgroud)
问题是当我尝试运行它时出现以下错误
NoMethodError: undefined method `[]=' for 1:Fixnum
from (irb):6:in `block in irb_binding'
from (irb):6:in `each'
from (irb):6:in `reduce'
from (irb):6
Run Code Online (Sandbox Code Playgroud)
我可以像这样设置初始值,还是我错了?
您可以使用each_with_object更清晰的语法
[1,1,2,3,3,3,4,5,5].each_with_object(Hash.new(0)) { |number, hash| hash[number] += 1 }
Run Code Online (Sandbox Code Playgroud)
请注意,参数的顺序是反向的 |number, hash|
您可以使用reduce,但如果你想的话,你必须再次返回哈希:
[1,1,2,3,3,3,4,5,5].reduce(Hash.new(0)) do |hash,number|
hash[number] += 1
hash
end
Run Code Online (Sandbox Code Playgroud)
没有它,hash[number]将返回值.哈希赋值的值是值本身.该块基于您之前返回的值.
这意味着,在第一次之后它会尝试这样的事情:1[1] += 1这当然不起作用,因为Fixnums没有实现这个方法[]=.
我喜欢reduce与hash.update. 它返回数组,我不需要该; hash部分:
[1,1,2,3,3,3,4,5,5].reduce(Hash.new(0)) { |h, n| h.update(n => h[n].next) }
Run Code Online (Sandbox Code Playgroud)