ruby - sirve - Cómo encontrar una clave hash que contenga un valor coincidente
ruby wikipedia (10)
Dado que tengo el hash de clientes a continuación, ¿hay una forma rápida de Ruby (sin tener que escribir un guión de varias líneas) para obtener la clave dada, quiero que coincida con el id_cliente? Ej. ¿Cómo obtener la clave para client_id == "2180"
?
clients = {
"yellow"=>{"client_id"=>"2178"},
"orange"=>{"client_id"=>"2180"},
"red"=>{"client_id"=>"2179"},
"blue"=>{"client_id"=>"2181"}
}
Aquí hay una manera fácil de encontrar las claves de un valor dado:
clients = {
"yellow"=>{"client_id"=>"2178"},
"orange"=>{"client_id"=>"2180"},
"red"=>{"client_id"=>"2179"},
"blue"=>{"client_id"=>"2181"}
}
p clients.rassoc("client_id"=>"2180")
... y para encontrar el valor de una clave determinada:
p clients.assoc("orange")
le dará el par clave-valor.
De los documentos:
- (¿Objeto?) Detectar (ifnone = nil) {| obj | ...}
- (¿Objeto?) Find (ifnone = nil) {| obj | ...}
- (Objeto) detectar (ifnone = nil)
- (Object) find (ifnone = nil)
Pasa cada entrada en enumeración para bloquear. Devuelve el primero para el cual el bloque no es falso. Si no coincide ningún objeto, llama a ifnone y devuelve su resultado cuando se especifica, o devuelve nil en caso contrario.
Si no se proporciona ningún bloque, se devuelve un enumerador.
(1..10).detect {|i| i % 5 == 0 and i % 7 == 0 } #=> nil
(1..100).detect {|i| i % 5 == 0 and i % 7 == 0 } #=> 35
Esto funcionó para mí:
clients.detect{|client| client.last[''client_id''] == ''2180'' } #=> ["orange", {"client_id"=>"2180"}]
clients.detect{|client| client.last[''client_id''] == ''999999'' } #=> nil
Ver: http://rubydoc.info/stdlib/core/1.9.2/Enumerable#find-instance_method
La mejor manera de encontrar la clave para un valor particular es usar el método clave que está disponible para un hash ....
gender = {"MALE" => 1, "FEMALE" => 2}
gender.key(1) #=> MALE
Espero que resuelva tu problema ...
Otro enfoque que probaría es usar #map
clients.map{ |key, _| key if clients[key] == {"client_id"=>"2180"} }.compact
#=> ["orange"]
Esto devolverá todas las ocurrencias de un valor dado. El guión bajo significa que no necesitamos que el valor de la clave se transmita para que no se asigne a una variable. La matriz contendrá nils si los valores no coinciden, por eso puse #compact
al final.
Podría usar hashname.key (valuename)
O bien, una inversión puede estar en orden. new_hash = hashname.invert
le dará un new_hash
que le permite hacer las cosas de manera más tradicional.
Puede usar Enumerable#select :
clients.select{|key, hash| hash["client_id"] == "2180" }
#=> [["orange", {"client_id"=>"2180"}]]
Tenga en cuenta que el resultado será una matriz de todos los valores coincidentes, donde cada uno es una matriz de la clave y el valor.
Puedes invertir el hash. clients.invert["client_id"=>"2180"]
devuelve "orange"
Según ruby doc http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-key (value) es el método para encontrar la clave en la base del valor.
ROLE = {"customer" => 1, "designer" => 2, "admin" => 100}
ROLE.key(2)
devolverá al "diseñador".
prueba esto:
clients.find{|key,value| value["client_id"] == "2178"}.first
Ruby 1.9 y superior:
hash.key(value) => key
Ruby 1.8 :
Podría usar hash.index
hsh.index(value) => key
Devuelve la clave para un valor dado. Si no se encuentra, devuelve
nil
.
h = { "a" => 100, "b" => 200 }
h.index(200) #=> "b"
h.index(999) #=> nil
Entonces, para obtener "orange"
, podrías usar:
clients.key({"client_id" => "2180"})