Velocity Reviews > Ruby > Hash of Hash of Arrays Question

# Hash of Hash of Arrays Question

Älphä Blüë
Guest
Posts: n/a

 07-18-2009
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[i]][:numbers] = myvaluearray[i]
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[i]
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üë
Guest
Posts: n/a

 07-18-2009
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üë
Guest
Posts: n/a

 07-18-2009
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üë
Guest
Posts: n/a

 07-18-2009
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/.

Gary Wright
Guest
Posts: n/a

 07-18-2009

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

Älphä Blüë
Guest
Posts: n/a

 07-18-2009
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/.

 Thread Tools

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post rp C++ 1 11-10-2011 04:45 PM Philipp Java 21 01-20-2009 08:33 AM Adam Akhtar Ruby 5 03-25-2008 11:53 PM Lynn Perl Misc 9 02-16-2005 06:59 PM Tore Aursand Perl Misc 3 09-16-2003 10:14 AM

Advertisments