# call-seq:
# StatisticsUtils.merge_sum(hash1, hash2, ...) -> merged_hash
#
# Merges the results of two statistics hashes, adding the counts when the keys double up.
#
# Example:
# StatisticsUtils.merge_sum({'a'=>1, 'b'=>1}, {'b'=>1, 'c'=>1}) -> {'a'=>1, 'b'=>2, 'c'=>1}
#
def self.merge_sum(*hashes)
total_hash = {}
hashes.each do |hash|
hash.each_pair do |key, value|
total_hash[key] ||= 0
total_hash[key] += value
end
end
total_hash
end
Refactorings
No refactoring yet !
danielharan
July 8, 2009, July 08, 2009 02:03, permalink
Using Rails' K combinator, returning (http://api.rubyonrails.org/classes/Object.html#M000311) and a Hash with a default value:
def self.merge_sum_new(*hashes)
returning(Hash.new {|h,k| h[k] = 0}) do |new_hash|
hashes.each do |hash|
hash.each_pair do |key, value|
new_hash[key] += value
end
end
end
end
Adam
July 8, 2009, July 08, 2009 03:00, permalink
require 'activesupport'
module StatisticsUtils
def self.merge_sum(*hashes)
hashes.each_with_object(Hash.new(0)) do |hash,result|
hash.each { |key,value| result[key] += value }
end
end
end
module StatisticsUtils
def self.merge_sum(*hashes)
hashes.inject(Hash.new(0)) do |result,hash|
hash.each { |key,value| result[key] += value }
result
end
end
end
This is obviously not very Ruby-ish because I had to explicitly return the totalled hash at the end, but it does the job.
Is there a good way of doing this in a chained fashion?