Extrahieren des spezifischen Wertes aus einem mehrdimensionalen Hash in Ruby mit dem Schlüsseldamen
-
19-09-2019 - |
Frage
Nehmen wir an, ich habe einen mehrdimensionalen Hash, und in einem der Unterhächen habe ich ein Schlüssel => Wertpaar, das ich nach Schlüssel abrufen muss. wie kann ich es tun?
Beispiel Hashes:
h={:x=>1,:y=>2,:z=>{:a=>{:k=>"needle"}}}
h={:k=>"needle"}
Schlüssel ist immer: k, und ich muss "Nadel" bekommen
Mir ist aufgefallen, dass es in Ruby 1.8 keine "abgeflachte" Funktion für Hashes gibt, aber wenn es da wäre, stelle ich mir vor, ich würde es einfach tun
h.flatten[:k]
Ich kann mir vorstellen, dass ich dafür eine rekursive Funktion schreiben muss?
Danke
Lösung
Sie können immer Ihre eigene missionsspezifische Erweiterung in Hash schreiben, die die Drecksarbeit für Sie erledigt:
class Hash
def recursive_find_by_key(key)
# Create a stack of hashes to search through for the needle which
# is initially this hash
stack = [ self ]
# So long as there are more haystacks to search...
while (to_search = stack.pop)
# ...keep searching for this particular key...
to_search.each do |k, v|
# ...and return the corresponding value if it is found.
return v if (k == key)
# If this value can be recursively searched...
if (v.respond_to?(:recursive_find_by_key))
# ...push that on to the list of places to search.
stack << v
end
end
end
end
end
Sie können dies ganz einfach verwenden:
h={:x=>1,:y=>2,:z=>{:a=>{:k=>"needle"}}}
puts h.recursive_find_by_key(:k).inspect
# => "needle"
h={:k=>"needle"}
puts h.recursive_find_by_key(:k).inspect
# => "needle"
puts h.recursive_find_by_key(:foo).inspect
# => nil
Andere Tipps
Wenn Sie einfach den Schlüsselwert holen müssen, aber nicht wissen, wie tief der Schlüssel ist, verwenden Sie diesen Snippet
def find_tag_val(hash, tag)
hash.map do |k, v|
return v if k.to_sym == tag
vr = find_tag_val(v, tag) if v.kind_of?(Hash)
return vr if vr
end
nil #othervice
end
h = {message: { key: 'val'}}
find_tag_val(h, :key) #=> 'val'