hash of arrays - appending to one of the arrays

Discussion in 'Ruby' started by Adam Akhtar, Mar 25, 2008.

  1. Adam Akhtar

    Adam Akhtar Guest

    Hi Ive done a search on this and there have been quite a few posts which
    have incresed my knowlege somewhat but still have a few questions.

    Im creating a hash of arrays. The keys and values are added within a
    loop. For each key there may be multiple values hence the need for an
    array as a value. Values for a key are found over interations of a loop.
    I therefore have to append a new found value to the existing values in
    an array.

    I tried doing this

    something.each do |blah|
    if (test something)
    hash[key] = hash[key] + value
    end
    end

    but the compliler complains about there being no method for nil class.

    I read the basic way to do this would be

    hash[key] = [] #create blank array
    hash[key] = hash[key] + value

    but as im in a loop that would require me to do a check to see if the
    key exists or not. If im processing lots of informatino that would slow
    me down a bit.

    IS there a slicker way of doing this?
    --
    Posted via http://www.ruby-forum.com/.
     
    Adam Akhtar, Mar 25, 2008
    #1
    1. Advertising

  2. Hi --

    On Tue, 25 Mar 2008, Adam Akhtar wrote:

    > Hi Ive done a search on this and there have been quite a few posts which
    > have incresed my knowlege somewhat but still have a few questions.
    >
    > Im creating a hash of arrays. The keys and values are added within a
    > loop. For each key there may be multiple values hence the need for an
    > array as a value. Values for a key are found over interations of a loop.
    > I therefore have to append a new found value to the existing values in
    > an array.
    >
    > I tried doing this
    >
    > something.each do |blah|
    > if (test something)
    > hash[key] = hash[key] + value
    > end
    > end
    >
    > but the compliler complains about there being no method for nil class.
    >
    > I read the basic way to do this would be
    >
    > hash[key] = [] #create blank array
    > hash[key] = hash[key] + value
    >
    > but as im in a loop that would require me to do a check to see if the
    > key exists or not. If im processing lots of informatino that would slow
    > me down a bit.
    >
    > IS there a slicker way of doing this?


    The most common idiom is:

    (hash[key] ||= []) << value

    You can also make a hash that has a default behavior, for non-existent
    keys, of putting an array at that key:

    irb(main):004:0> hash = Hash.new {|h,k| h[k] = [] }
    => {}
    irb(main):005:0> hash[1] << 2
    => [2]
    irb(main):006:0> hash
    => {1=>[2]}


    David

    --
    Upcoming Rails training from David A. Black and Ruby Power and Light:
    ADVANCING WITH RAILS April 14-17 New York City
    INTRO TO RAILS June 9-12 Berlin
    ADVANCING WITH RAILS June 16-19 Berlin
    CORE RAILS June 24-27 London (Skills Matter)
    See http://www.rubypal.com for more info!
     
    David A. Black, Mar 25, 2008
    #2
    1. Advertising

  3. Adam Akhtar

    Adam Akhtar Guest


    > The most common idiom is:
    >
    > (hash[key] ||= []) << value
    >


    Thanks for the reply. Can I ask what these || mean..in this case do they
    mean OR???

    does anyone have any good links on using the use of arrays with hashes
    in this manner?

    --
    Posted via http://www.ruby-forum.com/.
     
    Adam Akhtar, Mar 25, 2008
    #3
  4. On Tue, Mar 25, 2008 at 1:41 PM, Adam Akhtar <> wrote:
    >
    > > The most common idiom is:
    > >
    > > (hash[key] ||= []) << value
    > >

    >
    > Thanks for the reply. Can I ask what these || mean..in this case do they
    > mean OR???


    a ||= b means a = a || b

    and it's a common idiom to assign a value only when the lhs is nil (or false).
    A hash by default will return nil for non-existing keys so:

    hash[key] ||= [] could be written as hash[key] = hash[key] || []

    and means: if the key is not present in the hash, create that entry in
    the hash with an empty array as the value.

    > does anyone have any good links on using the use of arrays with hashes
    > in this manner?


    I don't have a link, but if you are doing that in a lot of places, remember you
    can change the default behaviour of a hash to do the above for you:

    hash = Hash.new {|h,k| h[k] = []}

    from there on you can say just:

    hash[key] << value

    because the default value for an inexistent key will trigger the
    creation of a new array assigned to that key.

    Jesus.
     
    Jesús Gabriel y Galán, Mar 25, 2008
    #4
  5. Hi --

    On Tue, 25 Mar 2008, Adam Akhtar wrote:

    >
    >> The most common idiom is:
    >>
    >> (hash[key] ||= []) << value
    >>

    >
    > Thanks for the reply. Can I ask what these || mean..in this case do they
    > mean OR???


    Yes. This:

    a ||= b

    is the same as:

    a or a = b

    I used to describe it like this:

    a = a || b

    but there are some edge cases where that doesn't apply (having to do
    with hash defaults, actually, but you don't need to worry about it in
    this case). Matz clarified it with the "or" version at RubyConf last
    year.

    > does anyone have any good links on using the use of arrays with hashes
    > in this manner?


    I don't know -- I just sort of use them :)


    David

    --
    Rails training from David A. Black and Ruby Power and Light:
    ADVANCING WITH RAILS April 14-17 New York City
    INTRO TO RAILS June 9-12 Berlin
    ADVANCING WITH RAILS June 16-19 Berlin
    See http://www.rubypal.com for details and updates!
     
    David A. Black, Mar 25, 2008
    #5
  6. Adam Akhtar

    Adam Akhtar Guest

    Adam Akhtar, Mar 25, 2008
    #6
    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. Nathan Gilbert

    Appending rows to 2-dim arrays

    Nathan Gilbert, Dec 7, 2005, in forum: C Programming
    Replies:
    1
    Views:
    283
    Michael Mair
    Dec 7, 2005
  2. JamesG
    Replies:
    8
    Views:
    345
    Patricia Shanahan
    Mar 7, 2007
  3. rp
    Replies:
    1
    Views:
    539
    red floyd
    Nov 10, 2011
  4. Doug Beaver
    Replies:
    1
    Views:
    104
    Robert Klemme
    Jul 16, 2003
  5. Srijayanth Sridhar
    Replies:
    19
    Views:
    627
    David A. Black
    Jul 2, 2008
Loading...

Share This Page