extraer valor específico de un hash multidimensional en el rubí por su nombre clave

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

  •  19-09-2019
  •  | 
  •  

Pregunta

Digamos que tiene un hash multidimensional, y en uno de los subhashes i tener una clave => valor de par, que necesito para recuperar por la clave. ¿Cómo puedo hacerlo?

ejemplo hashes:

h={:x=>1,:y=>2,:z=>{:a=>{:k=>"needle"}}}
h={:k=>"needle"}

clave es siempre: k, y necesito conseguir "aguja"

i di cuenta de que no hay ninguna función "aplanar" para los hashes en Ruby 1.8, pero si iba a estar allí, me imagino que acababa de hacer

h.flatten[:k]

Me imagino que necesito escribir una función recursiva para eso?

gracias

¿Fue útil?

Solución

Siempre se puede escribir su propia extensión específico de la misión en Hash, que hace el trabajo sucio para usted:

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

Puede utilizar esta simplemente:

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

Otros consejos

Si necesita simplemente en busca de valor clave, pero no sé qué tan profundo es la clave, utilizar este fragmento

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'
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top