Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate nested hash that contains hash and/or Array

I have a hash, I am trying to extract the keys and values for it. The hash has a nested hash and/or array of hashes.

After checking this site and few samples I got the key and values. But having difficulty in extracting if its a 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 below code from how do i loop over a hash of hashes in ruby and Iterate over an deeply nested level of hashes 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 at v.is_hash?(Array) or v.is_a?(Array).

Am I missing something?

like image 364
user2300908 Avatar asked May 07 '13 05:05

user2300908


1 Answers

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

So to get exactly the output you would get if your method would work, you could implement it like this:

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
like image 179
Beat Richartz Avatar answered Sep 27 '22 20:09

Beat Richartz