Robert Dober
3/14/2007 6:14:00 AM
On 3/13/07, Trans <transfire@gmail.com> wrote:
> On Mar 13, 8:40 am, "Robert Dober" <robert.do...@gmail.com> wrote:
> > 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.
>
> I understand what youre saying --and I waited on posting this until
> others gave solutions. Though in this particular case I think there's
> some pretty good meat here, ie. the OpenCollection class I literally
> just made up on the spot. Of course that still leaves Enumerable#sum,
> but that's rather straight forward: a.inject(0){|s,n| s+=n;s}.
>
> The Functor was just a little playful plug. If you've ever seen the
> functor code you know it's a generalization of what the OpenCollection
> class is doing. I actually would like to see Functor included in
> Ruby's standard lib. But I haven't been able to convince Matz of it's
> usefulness. So I try to publicly use it when ever I get the chance.
>
> HTH,
> T.
>
>
>
OMG was I too rude, maybe? Probably just to stupid to really
understand your mail :(
The good thing is though that I understand now what you wanted to tell us.
And I am one of the greatest fans of magic dot.
Thx and sorry.
Robert
--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw