我在使用reduce语法时遇到问题。我有以下格式的哈希:
H = {"Key1" => 1, "Key2" => 2}
我想使用reduce来查找此函数中值的总和。
喜欢的东西
H.reduce(0) {|memo, elem| memo+=elem}
我知道这是错的。我不明白如何使elem成为哈希值。
答案 0 :(得分:70)
您可以通过将其分为2个变量来使elem
包含该值:
H.reduce(0) {|memo, (key, val)| memo += val}
答案 1 :(得分:31)
使用Enumerable#reduce
,如果哈希恰好为空,则可以获得nil
:
H.values.reduce(:+) # => 3
Hash.new.values.reduce(:+) # => nil
要在哈希为空时安全地获取0
,请使用:
H.values.reduce(0) { |sum,x| sum + x } # or...
H.reduce(0) { |sum,(key,val)| sum + val } # ...if you need to inspect the key
这是一个快速的基准,对于踢。请注意,仅减少值而不是键/值对中的值似乎要快一些:
user system total real
H.values.reduce(:+) 4.510000 0.080000 4.590000 ( 4.595229)
H.values.reduce(0) {...} 4.660000 0.080000 4.740000 ( 4.739708)
H.reduce(0) {...} 5.160000 0.070000 5.230000 ( 5.241916)
require 'benchmark'
size = 1_000
hash = Hash[* Array.new(size*2) { rand } ]
N=10_000
Benchmark.bm(24) do |x|
x.report('H.values.reduce(:+)') { N.times { hash.dup.values.reduce(:+) } }
x.report('H.values.reduce(0) {...}') { N.times { hash.dup.values.reduce(0) { |sum,x| sum + x } } }
x.report('H.reduce(0) {...}') { N.times { hash.dup.reduce(0) { |sum,(_,v)| sum + v } } }
end
答案 2 :(得分:5)
试试这个:
H.reduce(0) { |memo, elem| memo += elem[1] }
或
H.reduce(0) { |memo, (key, value)| memo += value }
答案 3 :(得分:2)
我知道我正在挖掘这个,但如果您碰巧使用Rails,.sum
method可以提供帮助:
H = {"Key1" => 1, "Key2" => 2}
=> {"Key1"=>1, "Key2"=>2}
> H.values.sum
=> 3
优点是它会在空哈希值上返回0
:
> {}.values.sum
=> 0
> {}.values.reduce(:+)
=> nil
我注意到只有在输入这个答案后它才是特定于Rails的。我知道OP没有添加Rails标签,但我认为它可能对人们停下来有用。
请注意,从Ruby 2.4.0开始,.sum
is now available。
答案 4 :(得分:1)
h = {"Key1" => 1, "Key2" => 2}
h.values.inject(0){|f,v| f += v.to_i }
# => 3
或
h.values.inject(:+)
# => 3
答案 5 :(得分:0)
如果是复杂的散列,则先将其映射到值数组,然后再减少可能会更容易:
values = H.map do |k, v|
# some complex logic here
end
values.reduce(:+)
如果阵列可能为空,则为values.reduce(0, :+)
。