Iterate a nested hash containing a hash and / or array

I have a hash, I'm trying to extract keys and values ​​for it. A hash has a nested hash and / or an array of hashes.

After checking this site and several samples, I got the key and values. But hard to extract if its an array of hashes.

Example:

{ :key1 => 'value1', :key2 => 'value2', :key3 => { :key4 => [{:key4_1 => 'value4_1', :key4_2 => 'value4_2'}], :key5 => 'value5' }, :key6 => { :key7 => [1,2,3], :key8 => { :key9 => 'value9' } } } 

So far I have code as I iterate over the hash hash in ruby and Iterate over deep nested hash levels in Ruby

 def ihash(h) h.each_pair do |k,v| if v.is_a?(Hash) || v.is_a?(Array) puts "key: #{k} recursing..." ihash(v) else # MODIFY HERE! Look for what you want to find in the hash here puts "key: #{k} value: #{v}" end end end 

But it fails with v.is_hash?(Array) or v.is_a?(Array) .

Did I miss something?

+7
source share
3 answers

It's not entirely clear what you might need, but Array and Hash implement each (which in the case of Hash is an alias for each_pair ).

So, to get exactly the result that you get if your method works, you can implement it as follows:

 def iterate(h) h.each do |k,v| # If v is nil, an array is being iterated and the value is k. # If v is not nil, a hash is being iterated and the value is v. # value = v || k if value.is_a?(Hash) || value.is_a?(Array) puts "evaluating: #{value} recursively..." iterate(value) else # MODIFY HERE! Look for what you want to find in the hash here # if v is nil, just display the array value puts v ? "key: #{k} value: #{v}" : "array value #{k}" end end end 
+17
source

You call ihash (v) if v is an array or hash. calling each_pair will not be done for arrays.

+1
source

You can skip recursion and use something like this:

 a = {} a[0] = { first: "first" } a[1] = [{ second: "second_1" }, { second: "second_2" }] a.each_pair do |k1, v1| puts "======== key: #{k1}, value: ========" if v1.class == Hash v1.each_pair do |k2, v2| puts "key_2: #{k2}, value: #{v2}" end else v1.each do |h| h.each_pair do |k2, v2| puts "hash #{v1.index(h)} => key_2: #{k2}, value: #{v2}" end end end end 

Output:

 ======== key: 0, value: ======== key_2: first, value: first ======== key: 1, value: ======== hash 0 => key_2: second, value: second_1 hash 1 => key_2: second, value: second_2 
0
source

All Articles