non-destructive merging of hashes in array

Discussion in 'Ruby' started by Giles Bowkett, Mar 13, 2007.

  1. 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.

    --
    Giles Bowkett
    http://www.gilesgoatboy.org
    http://gilesbowkett.blogspot.com
    http://giles.tumblr.com/
    Giles Bowkett, Mar 13, 2007
    #1
    1. Advertising

  2. Giles Bowkett

    Robert Dober Guest

    On 3/13/07, Giles Bowkett <> wrote:
    <snip>
    > It can be crammed all onto one line, too, but there must be a nicer way.


    Maybe but I like my 5 lines already ;)

    r=Hash.new{|h,k| h[k]=0}
    hashes.each{
    |hash|
    hash.each{ |k,v| r[k]+= v }
    }

    HTH
    Robert
    >
    > --
    > Giles Bowkett
    > http://www.gilesgoatboy.org
    > http://gilesbowkett.blogspot.com
    > http://giles.tumblr.com/
    >
    >



    --
    We have not succeeded in answering all of our questions.
    In fact, in some ways, we are more confused than ever.
    But we feel we are confused on a higher level and about more important things.
    -Anonymous
    Robert Dober, Mar 13, 2007
    #2
    1. Advertising

  3. Giles Bowkett

    Robert Dober Guest

    On 3/13/07, Mushfeq Khan <> wrote:
    > How's this:
    >
    > hashes.inject({}) {|result, hash| result.merge(hash) {|k, e, v| (result[k]
    > || 0) + v}}
    >
    > or similarly:
    >
    > hashes.inject(Hash.new {|h, k| 0}) {|result, hash| result.merge(hash) {|k,
    > e, v| result[k] + v}}


    I bow to superior technique, the merge block form is particularly nice.

    >
    > Mushfeq.
    >

    Robert
    --
    We have not succeeded in answering all of our questions.
    In fact, in some ways, we are more confused than ever.
    But we feel we are confused on a higher level and about more important things.
    -Anonymous
    Robert Dober, Mar 13, 2007
    #3
  4. Giles Bowkett, Mar 13, 2007
    #4
  5. On Mar 12, 8:39 pm, "Mushfeq Khan" <> wrote:
    > You can even do:
    >
    > hashes.inject(Hash.new {|h, k| 0}) {|result, hash| result.merge(hash) {|k,
    > e, v| e + v}}


    Oh, you beat me to it. I might add, though, that the parameters in
    the initializer block can be safely removed:

    hashes.inject(Hash.new {0}) {|memo, hash| memo.merge(hash) {|k,e,v| e
    + v}}

    Harrison Reiser
    Harrison Reiser, Mar 13, 2007
    #5
  6. Giles Bowkett

    Robert Dober Guest

    On 3/13/07, Harrison Reiser <> wrote:
    > On Mar 12, 8:39 pm, "Mushfeq Khan" <> wrote:
    > > You can even do:
    > >
    > > hashes.inject(Hash.new {|h, k| 0}) {|result, hash| result.merge(hash) {|k,
    > > e, v| e + v}}

    >
    > Oh, you beat me to it. I might add, though, that the parameters in
    > the initializer block can be safely removed:
    >
    > hashes.inject(Hash.new {0}) {|memo, hash| memo.merge(hash) {|k,e,v| e
    > + v}}
    >
    > Harrison Reiser
    >

    and my humble contribution gives:

    hashes.inject{|memo, hash| memo.merge(hash) {|k,e,v| e+ v}}

    which is - as Gilles guessed correctly - a concise oneliner, boy I love Ruby.

    Robert
    --
    We have not succeeded in answering all of our questions.
    In fact, in some ways, we are more confused than ever.
    But we feel we are confused on a higher level and about more important things.
    -Anonymous
    Robert Dober, Mar 13, 2007
    #6
  7. Giles Bowkett

    Trans Guest

    On Mar 12, 10:01 pm, "Giles Bowkett" <> 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}}

    oc.rabbits.sum

    T.
    Trans, Mar 13, 2007
    #7
  8. Giles Bowkett

    Robert Dober Guest

    On 3/13/07, Trans <> wrote:
    >
    >
    > On Mar 12, 10:01 pm, "Giles Bowkett" <> 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}}
    >
    > 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.

    Cheers
    Robert

    --
    You see things; and you say Why?
    But I dream things that never were; and I say Why not?
    -- George Bernard Shaw
    Robert Dober, Mar 13, 2007
    #8
  9. Giles Bowkett

    Trans Guest

    On Mar 13, 8:40 am, "Robert Dober" <> wrote:
    > On 3/13/07, Trans <> wrote:
    >
    >
    >
    > > On Mar 12, 10:01 pm, "Giles Bowkett" <> 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}}

    >
    > > 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.
    Trans, Mar 13, 2007
    #9
  10. Giles Bowkett

    Robert Dober Guest

    On 3/13/07, Trans <> wrote:
    > On Mar 13, 8:40 am, "Robert Dober" <> wrote:
    > > On 3/13/07, Trans <> wrote:
    > >
    > >
    > >
    > > > On Mar 12, 10:01 pm, "Giles Bowkett" <> 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}}

    > >
    > > > 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
    Robert Dober, Mar 14, 2007
    #10
  11. The functor seems pretty cool. The sad thing is, I still have the most
    primitive implementation possible in my actual code. The reason is, I
    don't want to pop it in without fully understanding it.

    The memo solution looks cleanest, that's really just a gut feeling
    though. Let me just make sure I get it. Here it is:

    hashes.inject{|memo, hash| memo.merge(hash) {|k,e,v| e+ v}}

    Now partly it turns out my problem is slightly more complicated. It's
    not an array of hashes; it's an array of objects which can return
    hashes. So it basically looks like this:

    def enter_output
    @items = get_the_items
    @happy_output_hash = {}
    # non-destructively merge all hashes within @items into one hash
    @items.each do |item|
    item.hash_within.each do |key, value|
    if @happy_output_hash[key]
    @happy_output_hash[key] += value
    else
    @happy_output_hash[key] = value
    end
    end
    end
    end

    (Code altered to enhance obviousness.)

    Would the correct translation of the memo solution to accomodate this
    be something like this?

    items.inject{|happy_output_hash, item|
    happy_output_hash.merge(item.hash_within) {|k,e,v| e + v}}

    Also, what does the Functor solution actually do? That sounds Lispy,
    which appeals to me, but I want to be sure the code is maintainable by
    lesser mortals, such as, for example, me.

    --
    Giles Bowkett
    http://www.gilesgoatboy.org
    http://gilesbowkett.blogspot.com
    http://giles.tumblr.com/


    On 3/13/07, Trans <> wrote:
    > On Mar 13, 8:40 am, "Robert Dober" <> wrote:
    > > On 3/13/07, Trans <> wrote:
    > >
    > >
    > >
    > > > On Mar 12, 10:01 pm, "Giles Bowkett" <> 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}}

    > >
    > > > 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.
    >
    >
    >
    Giles Bowkett, Mar 14, 2007
    #11
  12. Giles Bowkett

    Trans Guest

    On Mar 14, 4:49 pm, "Giles Bowkett" <> wrote:
    > The functor seems pretty cool. The sad thing is, I still have the most
    > primitive implementation possible in my actual code. The reason is, I
    > don't want to pop it in without fully understanding it.
    >
    > The memo solution looks cleanest, that's really just a gut feeling
    > though. Let me just make sure I get it. Here it is:
    >
    > hashes.inject{|memo, hash| memo.merge(hash) {|k,e,v| e+ v}}
    >
    > Now partly it turns out my problem is slightly more complicated. It's
    > not an array of hashes; it's an array of objects which can return
    > hashes. So it basically looks like this:
    >
    > def enter_output
    > @items = get_the_items
    > @happy_output_hash = {}
    > # non-destructively merge all hashes within @items into one hash
    > @items.each do |item|
    > item.hash_within.each do |key, value|
    > if @happy_output_hash[key]
    > @happy_output_hash[key] += value
    > else
    > @happy_output_hash[key] = value
    > end
    > end
    > end
    > end
    >
    > (Code altered to enhance obviousness.)
    >
    > Would the correct translation of the memo solution to accomodate this
    > be something like this?
    >
    > items.inject{|happy_output_hash, item|
    > happy_output_hash.merge(item.hash_within) {|k,e,v| e + v}}


    Should work. Or you could split it into two lines if it's easier to
    read:

    hashes = items.collect{ |item| item.hash_within }

    > Also, what does the Functor solution actually do? That sounds Lispy,
    > which appeals to me, but I want to be sure the code is maintainable by
    > lesser mortals, such as, for example, me.


    (Depending on what your doing exactly) the inject/merge is probably
    just fine.

    Functor is pretty straight forward. The basic definition is:

    class Functor
    def initialize(*objs, &block)
    @objs = objs
    @block = block
    end
    def method_missing(sym,*args)
    @block.call(@sym,*(@objs + args))
    end
    end

    T.
    Trans, Mar 14, 2007
    #12
  13. Giles Bowkett 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}


    res = Hash.new(0) # to give the new keys a sensible default
    bunnies.each {|arr| arr.each { | key, value | res[key] += value }}

    P.S.: I thought about
    res = {}
    bunnies.each {|arr| arr.each { | key, value | (res[key]||=0) += value }}

    but (res[key]||=0) is not a lvalue. It was even considered a syntax
    error with the helpfull error message of:

    syntax error, unexpected tOP_ASGN, expecting '}'

    --
    Posted via http://www.ruby-forum.com/.
    Jenda Krynicky, Mar 15, 2007
    #13
  14. Giles Bowkett

    Jacob Fugal Guest

    On 3/14/07, Giles Bowkett <> wrote:
    > Would the correct translation of the memo solution to accomodate this
    > be something like this?
    >
    > items.inject{|happy_output_hash, item|
    > happy_output_hash.merge(item.hash_within) {|k,e,v| e + v}}


    There is a subtle difference between

    hashes.inject(Hash.new {0}) {|memo, hash| memo.merge(hash) {|k,e,v| e + v}}
    hashes.inject{|memo, hash| memo.merge(hash) {|k,e,v| e + v}}

    (and by extension, your suggestion above, which is a correct
    adaptation of the latter).

    The optional parameter to inject provides a "seed" value. If no seed value is
    provided, the first element of the enumerable is used as the seed and the block
    evaluated over the tail only. In most cases this won't matter, and using an
    argumentless inject is hunky-dory. But there are two gotchas:

    1) If the array is empty, providing no seed means that +nil+ will be used as
    the seed value. Probably not what you want as you'll get a NoMethodError for
    nil#merge.

    2) If not all the hashes in the array have the same keys, you'll probably get
    some NoMethodErrors for nil#+. That's the reason the seed hash in the former
    version provides an explicit default value.

    Jacob Fugal
    Jacob Fugal, Mar 15, 2007
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ville Vainio
    Replies:
    11
    Views:
    470
    Ville Vainio
    Apr 6, 2005
  2. Daniel Pitts

    Re: Non destructive read of socket

    Daniel Pitts, Oct 6, 2009, in forum: Java
    Replies:
    1
    Views:
    398
    Tom Anderson
    Oct 7, 2009
  3. kazaam
    Replies:
    12
    Views:
    263
    Matthias Wächter
    Sep 13, 2007
  4. Matt Brooks
    Replies:
    16
    Views:
    221
    Matt Brooks
    Sep 16, 2009
  5. Tim O'Donovan

    Hash of hashes, of hashes, of arrays of hashes

    Tim O'Donovan, Oct 27, 2005, in forum: Perl Misc
    Replies:
    5
    Views:
    202
Loading...

Share This Page