How to iterate over nested hashes?

Hi,

I have a data structure like this: {1=>{"foo"=>["bar", "baz"]}}

...and I can iterate over it with this:

c.values.each do |foo|
  foo.values.each do |bar|
    bar.each do |baz|
      p baz
    end
  end
end

But why can't I do this? (fails):

c.values.each.values.each.each do |foo|
  p foo
end

Any help much appreciated!

···

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

Andrew S. wrote in post #1068825:

But why can't I do this? (fails):

c.values.each.values.each.each do |foo|
  p foo
end

Because that's not how "each" works. You cannot call a method on "each"
in order to call it on every element. The "each" method without a block
returns an Enumerator.

So you'll either have to stick with the solution above or write your own
method. Or you should rethink the structure of your data. A deeply
nested hash or array is almost always bad design and should be replaced
with with an appropriate object (like a table, a tree or whatever fits
best).

···

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

Well, even if you could do that, I don't find "each.each.each"
particularly clean. So it's really a problem of the data structure.

···

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

You can do something like this (just an idea)

module Enumerable
  def recursive_each &block
    (respond_to?(:each_value) ? each_value : each).each do |v|
      if v.respond_to? :recursive_each
        v.recursive_each(&block)
      else
        yield v
      end
    end
  end
end

c = {1=>{"foo"=>["bar", "baz"]}}

c.recursive_each do |v|
  puts v
end

···

On Mon, 16 Jul 2012 05:36:29 +0900 "Andrew S." <lists@ruby-forum.com> wrote:

Hi,

I have a data structure like this: {1=>{"foo"=>["bar", "baz"]}}

...and I can iterate over it with this:

c.values.each do |foo|
  foo.values.each do |bar|
    bar.each do |baz|
      p baz
    end
  end
end

But why can't I do this? (fails):

c.values.each.values.each.each do |foo|
  p foo
end

Any help much appreciated!

--
Sincerely yours,
Aleksey V. Zapparov A.K.A. ixti
FSF Member #7118
Mobile Phone: +34 677 990 688
Homepage: http://www.ixti.net
JID: zapparov@jabber.ru

*Origin: Happy Hacking!

Thanks. I was hoping that there was some super clean Ruby way to do
this, but apparently not. Back to the drawing board!

···

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