Hash of Hash of Arrays Question

Discussion in 'Ruby' started by Älphä Blüë, Jul 18, 2009.

  1. Hi all,

    I decided to take a deep look into hashes today and how hashes of arrays
    are handled. This is a bit of a grasp for me because most of the
    languages I've worked with, arrays are handled in just a few ways. With
    Ruby, it's much better.

    So, here are my questions using an example scenario I'm creating from
    scratch.

    Creating a new Hash:

    myhash = Hash.new {|h,k| h[k] = {} }
    myhash.class
    => Hash

    Creating two Arrays:

    mykeyarray = Array.[](1,2,3,4,5)
    => [1, 2, 3, 4, 5]

    myvaluearray = Array.[](10,20,30,40,50)
    => [10, 20, 30, 40, 50]

    5.times do |i|
    myhash[mykeyarray][:numbers] = myvaluearray
    end

    myhash.keys
    => [5, 1, 2, 3, 4]

    myhash.values
    => [{:numbers=>50}, {:numbers=>10}, {:numbers=>20}, {:numbers=>30},
    {:numbers=>40}]

    myhash.inspect
    => "{5=>{:numbers=>50}, 1=>{:numbers=>10}, 2=>{:numbers=>20},
    3=>{:numbers=>30}, 4=>{:numbers=>40}}"

    So, I would believe that this is a hash of hashes of arrays correct?

    Secondly, how would I parse information out of this hash? Creating them
    is easy. Extracting exactly the way I want - not so easy.

    Let me give you an example:

    I create a constant that stores the symbol I want to use for my table.

    MY_TABLE_FIELD = [:numbers]

    myhash.each do |key|
    values = {:compiled_on => Date.today.strftime('%Y-%m-%d')}
    MY_TABLE_FIELD.each_with_index do |field, i|
    values[field] = key
    end
    model.create values
    end

    .. this won't work ..

    I want to match the symbol in my hash with the symbol in my constant
    (which represents the table field). I want to update the table field
    with the value of the hash (10,20,30,40,50). They hash key would
    represent the id field (1,2,3,4,5).

    How can I accomplish this given the information provided?
    --
    Posted via http://www.ruby-forum.com/.
    Älphä Blüë, Jul 18, 2009
    #1
    1. Advertising

  2. I performed the following test which got some of the results from this
    hash of hashes..

    myhash.each_pair do |k,v|
    puts "My key is #{k}."
    v.each_pair do |key, value|
    puts "Inner Key = #{key} and Inner Value = #{value}"
    end
    end

    returns..

    My key is 5.
    Inner Key = numbers and Inner Value = 50
    My key is 5numbers50.
    My key is 3numbers30.
    My key is 1.
    Inner Key = numbers and Inner Value = 10
    My key is .
    My key is 4numbers40.
    My key is 2.
    Inner key = numbers and Inner Value = 20
    My key is 1numbers10.
    My key is 3.
    Inner key = numbers and Inner Value = 30
    My key is 4.
    Inner Key = numbers and Inner Value = 40
    My key is 2numbers20.


    I don't want this..

    I want..

    My key is 5.
    Inner Key = numbers and Inner Value = 50
    My key is 1.
    Inner Key = numbers and Inner Value = 10
    My key is 2.
    Inner key = numbers and Inner Value = 20
    My key is 3.
    Inner key = numbers and Inner Value = 30
    My key is 4.
    Inner Key = numbers and Inner Value = 40
    --
    Posted via http://www.ruby-forum.com/.
    Älphä Blüë, Jul 18, 2009
    #2
    1. Advertising

  3. Okay, I was pretty close...

    I figured this part out:

    myhash.each_pair do |k,v|
    v.each_pair do |key, value|
    puts "Key = #{k} and Inner Key = #{key} and Inner Value = #{value}"
    end
    end

    Returns:

    Key = 5 and Inner Key = numbers and Inner Value = 50
    Key = 1 and Inner Key = numbers and Inner Value = 10
    Key = 2 and Inner Key = numbers and Inner Value = 20
    Key = 3 and Inner Key = numbers and Inner Value = 30
    Key = 4 and Inner Key = numbers and Inner Value = 40

    So, that answers one part of my question...

    Now I have to figure out how to match this up to my constant fields..
    --
    Posted via http://www.ruby-forum.com/.
    Älphä Blüë, Jul 18, 2009
    #3
  4. Well I've spent several hours on this and can't figure out how to get
    everything matched up. I think the issue really comes down to the
    constant is an array of values and I'm comparing it to a hash which is a
    paired key+value..

    Therefore, I would probably have to convert my constant to a hash before
    using it with this.

    In any event, I'll stick with my original method although it's quite a
    bit sloppy looking...

    But,..

    myhash.each_pair do |k,v|
    v.each_pair do |key, value|
    puts "Key = #{k} and Inner Key = #{key} and Inner Value = #{value}"
    end
    end


    Does find exactly what I need for any future needs when required. So,
    at least I learned something. Now if I could just figure out how to
    sort a hash..
    --
    Posted via http://www.ruby-forum.com/.
    Älphä Blüë, Jul 18, 2009
    #4
  5. Älphä Blüë

    Gary Wright Guest

    On Jul 18, 2009, at 12:43 PM, =C4lph=E4 Bl=FC=EB wrote:
    > Does find exactly what I need for any future needs when required. So,
    > at least I learned something. Now if I could just figure out how to
    > sort a hash..


    Prior to Ruby 1.9, hashes are unsorted. In Ruby 1.9, hashes are
    maintained in insertion order. That is to say, if you iterate
    over the hash you'll get the key/value pairs in the order in
    which they were inserted into the hash.

    If you want to iterate over a hash according to some other
    order you'll need to do something like:

    hash =3D {2=3D>1, 1=3D>0, 3=3D>4}

    hash.sort_by {|k,v| k }.each { |k,v|
    puts "key: #{k}, value: #{v}"
    }


    key: 1, value: 0
    key: 2, value: 1
    key: 3, value: 4

    Note that sort_by doesn't return a hash but instead returns
    an array of key/value pairs:

    >> hash.sort_by { |k,v| v }

    =3D> [[1, 0], [2, 1], [3, 4]]


    Gary Wright
    Gary Wright, Jul 18, 2009
    #5
  6. Thanks Gary,

    I'd much rather be using 1.9.1 but unfortunately I have to stay with 1.8
    for now. I'll eventually make the switch when some gems/plugins I use
    move forward.

    Thanks!

    --
    Posted via http://www.ruby-forum.com/.
    Älphä Blüë, Jul 18, 2009
    #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. Philipp
    Replies:
    21
    Views:
    1,127
    Philipp
    Jan 20, 2009
  2. rp
    Replies:
    1
    Views:
    520
    red floyd
    Nov 10, 2011
  3. Adam Akhtar
    Replies:
    5
    Views:
    649
    Adam Akhtar
    Mar 25, 2008
  4. Tore Aursand
    Replies:
    3
    Views:
    552
    Anno Siegel
    Sep 16, 2003
  5. Lynn

    Accessing Hash of hash of arrays

    Lynn, Feb 14, 2005, in forum: Perl Misc
    Replies:
    9
    Views:
    546
    Alan J. Flavell
    Feb 16, 2005
Loading...

Share This Page