Extrahieren des spezifischen Wertes aus einem mehrdimensionalen Hash in Ruby mit dem Schlüsseldamen

StackOverflow https://stackoverflow.com/questions/2238849

  •  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

War es hilfreich?

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'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top