¿Cómo busco dentro de una matriz de valores hash por valores hash en ruby?


234

Tengo una variedad de hashes, @fathers.

a_father = { "father" => "Bob", "age" =>  40 }
@fathers << a_father
a_father = { "father" => "David", "age" =>  32 }
@fathers << a_father
a_father = { "father" => "Batman", "age" =>  50 }
@fathers << a_father 

¿Cómo puedo buscar en esta matriz y devolver una matriz de hashes para los que un bloque devuelve verdadero?

Por ejemplo:

@fathers.some_method("age" > 35) #=> array containing the hashes of bob and batman

Gracias.

Respuestas:


419

Estás buscando Enumerable # select (también llamado find_all):

@fathers.select {|father| father["age"] > 35 }
# => [ { "age" => 40, "father" => "Bob" },
#      { "age" => 50, "father" => "Batman" } ]

Según la documentación, "devuelve una matriz que contiene todos los elementos de [el enumerable, en este caso @fathers] para el que el bloque no es falso".


22
Oh! ¡Fuiste el primero! Eliminando mi respuesta y +1.
Milan Novota

20
Como nota, si solo desea encontrar uno solo (el primero) puede usarlo @fathers.find {|father| father["age"] > 35 }en su lugar.
Leigh McCulloch

1
¿Es posible devolver el índice de dónde se encontró esto en la matriz original de hashes?
Ian Warner

1
@IanWarner Sí. Sugiero mirar los documentos para el módulo Enumerable. Si aún no puede resolverlo, publique una nueva pregunta.
Jordan Running

Acabo de hacer este índice = ARRAY.index {| h | h [: code] == ARRAY ["code"]}
Ian Warner

198

esto devolverá el primer partido

@fathers.detect {|f| f["age"] > 35 }

66
Prefiero esto antes #select, pero todo vale para su caso de uso. #detectregresará nilsi no se encuentra una coincidencia, mientras que #select, en la respuesta de @ Jordan, regresará [].
TJ Biddle

13
También puede usar en findlugar de detectun código más legible
Alter Lagos el

8
findSin embargo, puede ser confuso en los rieles.
user12341234

55
selecty detectno son iguales, selectatravesarán toda la matriz, mientras que detectse detendrán tan pronto como se encuentre la primera coincidencia. Si estás buscando UN partido @fathers.select {|f| f["age"] > 35 }.firstcontra @fathers.detect {|f| f["age"] > 35 } rendimiento y legibilidad, mi voto es paradetect
Naveed

35

si su matriz se ve así

array = [
 {:name => "Hitesh" , :age => 27 , :place => "xyz"} ,
 {:name => "John" , :age => 26 , :place => "xtz"} ,
 {:name => "Anil" , :age => 26 , :place => "xsz"} 
]

Y desea saber si algún valor ya está presente en su matriz. Utilice el método de búsqueda

array.find {|x| x[:name] == "Hitesh"}

Esto devolverá el objeto si Hitesh está presente en el nombre, de lo contrario, devuelve nil


Si el nombre era minúscula "hitesh", no devolverá el hash. ¿Cómo podemos explicar también el uso de mayúsculas y minúsculas en tales casos?
arjun

2
puedes usar algo como array.find {| x | x [: name] .downcase == "Hitesh" .downcase}
Hitesh Ranaut el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.