Merge array of hashes, keeping duplicate values as arrays I am working on a Ruby gem to pull data from the Wikidata API.  The data is deeply nested, as it contains a lot of repetition.

I have written a piece of Ruby (sans Rails) code that enables an array of hashes to be merged together, with any duplicate key-value pairs being stored as an array under the same key.

For example:

[{:a=&gt;1, :b=&gt;2}, {:b=&gt;3, :c=&gt;4}, {:d=&gt;5, :a=&gt;6}].merge_hashes


gives:

{:a=&gt;[1, 6], :b=&gt;[2, 3], :c=&gt;4, :d=&gt;5}


I began with the following:

class Array
  def merge_hashes
    raise StandardError.new "Array is not an Array of Hashes" unless self.all? {|e| e.is_a? Hash}
    self.each_with_object({}) do |el, h|
      el.each do |k, v|
        if h[k].nil?
          h[k] = v
        else
          h[k] = Array.new([h[k]]) &lt;&lt; v
          h[k] = h[k].flatten
        end
      end
    end
  end
end


And refactored to:

class Array
def merge_hashes
    raise StandardError.new "Array is not an Array of Hashes" unless self.all? {|e| e.is_a? Hash}
    self.each_with_object({}) { |el, h| el.each { |k, v| h[k].nil? ? h[k] = v : h[k] = (Array.new([h[k]]) &lt;&lt; v).flatten } }
  end 
end


Are there any other improvements I could make?  Is that an acceptable exception to throw?
I think the refactor is barely readable, the first version is better. Anyway, if you use functional abstractions, instead of doing a imperative processing from scratch, algorithms tend to be more clear. 

In this case, we can use the abstraction Enumerable#map_by (a group_by variation where you can control both the grouping function and the accumulated values) and write:

require 'facets'

class Array
  def merge_hashes
    flat_map(&amp;:to_a).map_by { |k, v| [k, v] }
  end 
end


Note that this snippet always returns an array as a value, instead of the scalar/list you have.