How to Iterate over nested Hashes?

Hi,

I'm new to Ruby. I want to know how to iterate over a nested hash as
below.

···

*****************************************************************************
testhash = {

"recipeKey"=>{"title"=>"RailsBook", "category_id"=>"1",
"description"=>"This is a book about Rails", "instructions"=>"Read It"}

}
testhash.each {|key, value| print key, " value is : ", value, "\n" }

Here is the output i get..

==> recipeKey value is : titleRailsBookdescriptionThis is a book about
Railscategory_id1instructionsRead It
*****************************************************************************

As per the input "testhash", the value itself is a hash rt with keys as
"title","category_id","description" and "instructions"? Now how to get
these values as a key/value pair ??

If we apply "eash" operator for "testhash", the values are getting
printed "continously string" as shown above???, is this the expected
behaviour?

I tried to assign this value into a "new hash" variable and when i
applied "each" on this varibale, it said "each" varible undefined, the
reason may be that the value which i assinged is not a hash? so wanted
to know how to iterate the above nested hash ? Please help me out.

Thank You..

--
Posted via http://www.ruby-forum.com/.

Something like this might work

---------------------------------- 8< --------------------------
#!/usr/bin/env ruby

testhash = {
:outside => 1,
"recipeKey"=>{"title"=>"RailsBook", "category_id"=>"1",
"description"=>"This is a book about Rails", "instructions"=>"Read It",
  "author" => { :name => "Robert", :email => "<robert.dober@gmail.com>" }
},
:out_again => true

}

def traverse( aHash, level = 0 )
    aHash.each do
        >k, v|
        puts "%s%s:%s" % [ " " *level, k,
                v.kind_of?(Hash) ? traverse( v, level + 1) : v
                ]
    end # do
    ""
end # def traverse(

traverse testhash
---------------------------------- >8 --------------------------

hope that helps

Robert

···

On 3/24/06, Dinesh Dinesh <u_dinesh@yahoo.com> wrote:

Hi,

I'm new to Ruby. I want to know how to iterate over a nested hash as
below.

*****************************************************************************
testhash = {

"recipeKey"=>{"title"=>"RailsBook", "category_id"=>"1",
"description"=>"This is a book about Rails", "instructions"=>"Read It"}

}
testhash.each {|key, value| print key, " value is : ", value, "\n" }

Here is the output i get..

==> recipeKey value is : titleRailsBookdescriptionThis is a book about
Railscategory_id1instructionsRead It

*****************************************************************************

As per the input "testhash", the value itself is a hash rt with keys as
"title","category_id","description" and "instructions"? Now how to get
these values as a key/value pair ??

If we apply "eash" operator for "testhash", the values are getting
printed "continously string" as shown above???, is this the expected
behaviour?

I tried to assign this value into a "new hash" variable and when i
applied "each" on this varibale, it said "each" varible undefined, the
reason may be that the value which i assinged is not a hash? so wanted
to know how to iterate the above nested hash ? Please help me out.

Thank You..

--
Posted via http://www.ruby-forum.com/\.

--
Deux choses sont infinies : l'univers et la bêtise humaine ; en ce qui
concerne l'univers, je n'en ai pas acquis la certitude absolue.

- Albert Einstein

Dinesh Dinesh wrote:

Hi,

I'm new to Ruby. I want to know how to iterate over a nested hash as below.

*****************************************************************************
testhash = {

"recipeKey"=>{"title"=>"RailsBook", "category_id"=>"1", "description"=>"This is a book about Rails", "instructions"=>"Read It"}

}
testhash.each {|key, value| print key, " value is : ", value, "\n" }

Here is the output i get..

==> recipeKey value is : titleRailsBookdescriptionThis is a book about Railscategory_id1instructionsRead It
*****************************************************************************

As per the input "testhash", the value itself is a hash rt with keys as "title","category_id","description" and "instructions"? Now how to get these values as a key/value pair ??

If we apply "eash" operator for "testhash", the values are getting printed "continously string" as shown above???, is this the expected behaviour?

Yes, it's the result of a hash converted to string.

I tried to assign this value into a "new hash" variable and when i applied "each" on this varibale, it said "each" varible undefined, the reason may be that the value which i assinged is not a hash?

"each" is a method not a variable.

> so wanted

to know how to iterate the above nested hash ? Please help me out.

First of all you should describe what you want to see during the iteration. Do you only want to see key value pairs of nested hashes? Do you want to see key1,key2,value?

If you just want to print the whole Hash you can use pp:

>> require 'pp'
=> true
>> testhash = {
....
>> pp testhash
{"recipeKey"=>
   {"title"=>"RailsBook",
    "description"=>"This is a book about Rails",
    "category_id"=>"1",
    "instructions"=>"Read It"}}

Kind regards

  robert

Hi Robert,

Thank a LOT for the quick reply. Sorry for not making it clear when i
have posted it.

What i was looking is, if the "value" is a hash, then i want to assign
this value to another hash variable, so that upon iterating that hash
variable i should see the key/value pairs of this new value.

In our case even though the "value" was a hash i think while iterating
it gets converted to string and it is printing as "continious string".

I was thinking that if i create a new hash and assign the "value" (which
is a hash) to this new hash, then i can iterate it. But what i feel is
as you have mentioned we have to use some thing like "traverse" which
you have written to manipulate it.

So Is there any built-in "methods" to take care of situations like this
(nested - nested hash) than writing our own "traverse" methods like this
?

Again thanks for your quick and kind reply.

Dinesh

Robert Klemme wrote:

···

Dinesh Dinesh wrote:

"title","category_id","description" and "instructions"? Now how to get
these values as a key/value pair ??

If we apply "eash" operator for "testhash", the values are getting
printed "continously string" as shown above???, is this the expected
behaviour?

Yes, it's the result of a hash converted to string.

I tried to assign this value into a "new hash" variable and when i
applied "each" on this varibale, it said "each" varible undefined, the
reason may be that the value which i assinged is not a hash?

"each" is a method not a variable.

> so wanted

to know how to iterate the above nested hash ? Please help me out.

First of all you should describe what you want to see during the
iteration. Do you only want to see key value pairs of nested hashes?
Do you want to see key1,key2,value?

If you just want to print the whole Hash you can use pp:

>> require 'pp'
=> true
>> testhash = {
....
>> pp testhash
{"recipeKey"=>
   {"title"=>"RailsBook",
    "description"=>"This is a book about Rails",
    "category_id"=>"1",
    "instructions"=>"Read It"}}

Kind regards

  robert

--
Posted via http://www.ruby-forum.com/\.

Dinesh Umanath wrote:

Please don't top post.

Thank a LOT for the quick reply. Sorry for not making it clear when i
have posted it.

What i was looking is, if the "value" is a hash, then i want to assign
this value to another hash variable, so that upon iterating that hash
variable i should see the key/value pairs of this new value.

In our case even though the "value" was a hash i think while iterating
it gets converted to string and it is printing as "continious string".

No, it is converted during printing.

I was thinking that if i create a new hash and assign the "value" (which
is a hash) to this new hash, then i can iterate it. But what i feel is
as you have mentioned we have to use some thing like "traverse" which
you have written to manipulate it.

So Is there any built-in "methods" to take care of situations like this
(nested - nested hash) than writing our own "traverse" methods like this
?

No. Because there are plenty equally useful ways to do it. In some scenarios it might be required to see the whole path of keys in others the recursion depth is fixed...

It really depends on what you want to do.

Regards

  robert