2013-05-07 13 views
7

Ich habe einen Hash, ich versuche, die Schlüssel und Werte dafür zu extrahieren. Der Hash hat einen verschachtelten Hash und/oder ein Array von Hashes.Iterate verschachtelten Hash, der Hash und/oder Array enthält

Nach dem Überprüfen dieser Website und einige Proben habe ich den Schlüssel und die Werte. Aber Schwierigkeiten beim Extrahieren, wenn es ein Array von Hashes ist.

Beispiel:

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

Bisher habe ich unten Code haben von how do i loop over a hash of hashes in ruby und 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 

Aber es scheitert an v.is_hash?(Array) oder v.is_a?(Array).

Fehle ich etwas?

+1

was Ihre erwartete Ausgabe ist? –

Antwort

17

Es ist nicht ganz klar, was möchten Sie vielleicht, aber beide Array und Hash implementieren each (Dies ist im Fall von Hash ein Alias ​​für each_pair).

So zu bekommen genau die Ausgabe, die Sie, wenn Ihre Methode funktionieren würde, bekommen würde, könnte man es so implementieren:

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 
1

Sie rufen Ihash (v) auf, wenn v ein Array oder ein Hash ist. Der Aufruf der Methode "each_pair" schlägt für Arrays fehl.

0

Sie konnten die Rekursion überspringen und diese etwas mehr wie verwenden:

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 

Ausgang:

======== 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