42b570f6f4312a872c2fc671e3ddc82b

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?

# 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 !

880cbab435f00197613c9cc2065b4f5a

danielharan

July 8, 2009, July 08, 2009 02:03, permalink

No rating. Login to rate!

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
A8d3f35baafdaea851914b17dae9e1fc

Adam

July 8, 2009, July 08, 2009 03:00, permalink

No rating. Login to rate!
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

Your refactoring





Format Copy from initial code

or Cancel