On 3/13/07, Trans <transf...@gmail.com> wrote:
> 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.
Tom Facet is a great thing and I do not fail to point to it regulary.
But sometimes I feel we have to flex our muscles in pure Ruby before
we shall use libraries, even excellent ones like Facets, just to
understand everything a little better.
This all does not mean that your post is not very valuable, I just
want to warn from the "Pull In A Library before Do Some Thinking"
approach.
i fear that this approach hurts the user as much as the library.