Alex Rivera | Logout

Iterate over a deeply nested level of hashes in Ruby

Asked 2012-01-05T19:24:24.200
34

So I have a hash, and for each level of the hash, I want to store its key and value. The problem is, a value can be another hash array. Furthermore, that hash can contain key value pairs where the value is again another hash array, etc, etc. Also, I won't know how deeply nested each hash will be. To give an example:

{
  :key1 => 'value1',
  :key2 => 'value2',
  :key3 => {
     :key4 => 'value4',
     :key5 => 'value5'
   },
    :key6 => {
      :key7 => 'value7',
      :key8 => {
        :key9 => 'value9'
      }
    }
  }

..And so on. What I want to do is save each key, value pair and the id of its parent. I figure this will probably be done recursively, I'm just unsure how because I'm unfamiliar with recursive functions. I know how to iterate through the data normally:

  myHash.each {|key, value|
    ...Do something with the key and value ...
  }

And so I'm guessing the recursive call will be something like this:

def save_pair (myHash)
  myHash.each {|key, value|
    if(value.class != Hash) ? Pair.create(key, value) : save_pair(value)
  }
end

This is untested, and I'm still unsure how to incorporate saving the parent ids regardless.

Edit
Report

1 Answer

25

If I understand the goal, then you should be able to pass in the parent to your save method. For the top level, it will be nil. The following shows the idea where puts is used as a place holder for the "save".

def save_pair(parent, myHash)
  myHash.each {|key, value|
    value.is_a?(Hash) ? save_pair(key, value) :
            puts("parent=#{parent.nil? ? 'none':parent}, (#{key}, #{value})")
  }
end

Here is an example call to it:

hash = Hash.new
hash["key1"] = "value1"
hash["key2"] = "value2"
hash["key3"] = Hash.new
hash["key3"]["key4"] = "value4"
hash["key3"]["key5"] = "value5"
hash["key6"] = Hash.new
hash["key6"]["key7"] = "value7"
hash["key6"]["key8"] = Hash.new
hash["key6"]["key8"]["key9"] = "value9"

save_pair(nil, hash)
answered 2012-01-05T20:16:40.527

Your Answer