On Mar 12, 10:01 pm, "Giles Bowkett" <gil... / gmail.com> wrote:
> Hi, I have an array of hashes. The keys in the hashes represent the same things.
>
> eg:
>
> h1 = {:rabbits => 5}
> h2 = {:rabbits => 10}
>
> bunnies = [h1, h2]
>
> I want to end up with this:
>
> {:rabbits => 15}
>
> It's a trivial task, but what's the quickest way to get there? I'm
> certain it can be done on one line.
>
> I know there's a Hash#update, but it appears that it would just
> replace the 10 with 5, or vice versa, rather than adding them up.
>
> This works, but it seems clunky:
>
> hashes.each do |h|
>   h.each do |k, v|
>     if new_hash[k]
>       new_hash[k] += v
>     else
>       new_hash[k] = v
>     end
>   end
> end
>
> It can be crammed all onto one line, too, but there must be a nicer way.

(SORRY IF THIS GETS POSTED TWICE)

The inject/merge solutions are good, but they are one trick ponies.
How about something like:

   OpenCollection[h1, h2].rabbits.sum

It shouldn't be too hard to write:

   require 'ostruct'

   class OpenCollection
     class << self ; alias :[] :new ; end
     def initialize(*hashes)
       @opens = hashes.collect { |h| OpenStruct.new(h) }
     end

     def method_missing(sym, *args)
       @opens.collect{ |o| o.send(sym) }
     end
   end

Actually, I'd use Facets OpenObject instead OpenStruct myself, but
that's just me. You'll also need:

  require 'facets/core/enumerable/sum'

For fun, here's a one line version (more or less):

   require 'facets/more/functor'

   oc = Functor.new([h1,h2]){|s,m| m.map{|h| h[s]}}

   oc.rabbits.sum

T.