Reduce Hash Values
Use Enumerable#reduce
, if you're ok with getting nil
if the hash happens to be empty:
H.values.reduce(:+) # => 3Hash.new.values.reduce(:+) # => nil
To safely get 0
when the hash is empty, use:
H.values.reduce(0) { |sum,x| sum + x } # or...H.reduce(0) { |sum,(key,val)| sum + val } # ...if you need to inspect the key
Here's a quick benchmark, for kicks. Note that it appears to be slightly faster to reduce just the values rather than values from the key/value pairs:
user system total realH.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_000hash = Hash[* Array.new(size*2) { rand } ]N=10_000Benchmark.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