Ruby 减少数组时使用Hash.new作为初始值
我有一个这样的数组Ruby 减少数组时使用Hash.new作为初始值,ruby,hash,reduce,Ruby,Hash,Reduce,我有一个这样的数组 [1,1,2,3,3,3,4,5,5] 我想计算每个数字出现的次数,我正试着这样做 [1,1,2,3,3,3,4,5,5].reduce(Hash.new(0)) { |hash,number| hash[number] += 1 } 问题是,当我尝试运行它时,出现了以下错误 NoMethodError: undefined method `[]=' for 1:Fixnum from (irb):6:in `block in irb_binding' f
[1,1,2,3,3,3,4,5,5]
我想计算每个数字出现的次数,我正试着这样做
[1,1,2,3,3,3,4,5,5].reduce(Hash.new(0)) { |hash,number| hash[number] += 1 }
问题是,当我尝试运行它时,出现了以下错误
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
我可以这样设置初始值吗?还是我弄错了?您可以使用
reduce
,但如果需要,您必须再次返回哈希:
[1,1,2,3,3,3,4,5,5].reduce(Hash.new(0)) do |hash,number|
hash[number] += 1
hash
end
如果没有这个值,hash[number]
的值将被返回。散列赋值的值就是值本身。该块基于先前返回的值生成
这意味着,在第一次之后,它将尝试以下操作:1[1]+=1
,这当然不起作用,因为Fixnums没有实现可用于更简洁语法的方法
[1,1,2,3,3,3,4,5,5].each_with_object(Hash.new(0)) { |number, hash| hash[number] += 1 }
请注意,参数的顺序是相反的,即
| number,hash
我喜欢将reduce
与hash.update一起使用。它返回数组,我不需要;散列
部分:
[1,1,2,3,3,3,4,5,5].reduce(Hash.new(0)) { |h, n| h.update(n => h[n].next) }
你的问题已经得到了回答,但这里有另一种剥猫皮的方法:
[编辑以采纳@David的建议。]
a = [1,1,2,3,3,3,4,5,5]
Hash[a.group_by(&:to_i).map {|g| [g.first, g.last.size]}]
这也适用于:
a.group_by{|e| e}.inject({}) {|h, (k,v)| h[k] = v.size; h}
并且可以通过@spickermann使用update
(或者它的同义词merge!
)来改进,以摆脱那种恼人的;h
结尾处:
a.group_by{|e| e}.inject({}) {|h, (k,v)| h.merge!(k => v.size)}
以前,我有:
Hash[*a.group_by(&:to_i).to_a.map {|g| [g.first, g.last.size]}.flatten]
我不喜欢这里。我想使用来处理
而不是…按{x | x |}
分组{u>(在上面的一个解决方案中使用),并且正在寻找一种返回接收器或其值的方法m
to_i
是我能做的最好的方法(例如,2.to_i=>2
),但只适用于整数。有谁能建议一种方法,将一系列对象的接收器返回到proc,这些对象与一起使用时,其目的显而易见?这很简单:
[1,1,2,3,3,3,4,5,5].group_by {|e| e}.collect {|k,v| [k,v.count]}
#=> [[1, 2], [2, 1], [3, 3], [4, 1], [5, 2]]
如果哈希对象中需要结果
Hash[[1,1,2,3,3,3,4,5,5].group_by {|e| e}.collect {|k,v| [k,v.count]}]
#=> {1=>2, 2=>1, 3=>3, 4=>1, 5=>2}
我总是忘记有每个带有对象的\u
。我发现它比每次迭代都返回散列更干净。很好!我不熟悉update
。把它藏起来。(读者:请注意,如果不明显的话,他可以使用+1
而不是next
)。过于复杂;)您可以将代码简化为Hash[a.group_by(&:to_i).map{g |[g.first,g.last.size]}]
。哈希继承了可枚举的映射
,因此无需将其转换为数组
。此外,您还可以避免展平生成的数组,从而避免使用splat操作符。更不用说,您可以在块参数处拆分通过map
传递的对象。我同意Ruby缺少返回自身的.id
方法(被Haskell;)破坏了)