Forum: Ruby How to Iterate over nested Hashes ?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Dinesh U. (Guest)
on 2006-03-24 11:21
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..
Robert D. (Guest)
on 2006-03-24 11:40
(Received via mailing list)
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 => 
"<removed_email_address@domain.invalid>"
}
},
: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 D. <removed_email_address@domain.invalid> wrote:
> "recipeKey"=>{"title"=>"RailsBook", "category_id"=>"1",
> *****************************************************************************
> 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
Robert K. (Guest)
on 2006-03-24 11:44
(Received via mailing list)
Dinesh D. 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
Dinesh U. (Guest)
on 2006-03-24 12:27
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 K. wrote:
> Dinesh D. 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
Robert K. (Guest)
on 2006-03-24 15:14
(Received via mailing list)
Dinesh U. 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
This topic is locked and can not be replied to.