Come posso cercare all'interno di una matrice di hash per valori di hash in ruby?


234

Ho una serie di hash, @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 

Come posso cercare questo array e restituire un array di hash per cui un blocco ritorna vero?

Per esempio:

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

Grazie.

Risposte:


419

Stai cercando Enumerable # select (chiamato anche find_all):

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

Secondo la documentazione, "restituisce un array contenente tutti gli elementi di [l'enumerabile, in questo caso @fathers] per i quali il blocco non è falso."


22
Oh! Sei stato il primo! Eliminazione della mia risposta e +1.
Milano Novota,

20
Come nota, se volevi trovarne solo uno (il primo) puoi @fathers.find {|father| father["age"] > 35 }invece usarlo .
Leigh McCulloch,

1
È possibile restituire l'indice di dove è stato trovato nella matrice originale di hash?
Ian Warner,

1
@IanWarner Sì. Suggerisco di guardare i documenti per il modulo Enumerable. Se non riesci ancora a capirlo, pubblica una nuova domanda.
Giordania, in esecuzione il

Ho appena fatto questo indice = ARRAY.index {| h | h [: code] == ARRAY ["code"]}
Ian Warner,

198

questo restituirà la prima partita

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

6
Preferisco questo oltre #select- Ma tutto vale per il tuo caso d'uso. #detecttornerà nilse non viene trovata alcuna corrispondenza, mentre #select, nella risposta di @ Jordan, tornerà [].
TJ Biddle,

13
Puoi anche usare findinvece di detectun codice più leggibile
Lagos il

8
findpuò diventare confuso nelle rotaie, tuttavia.
user12341234

5
selecte detectnon sono gli stessi, selectattraverserà l'intero array, mentre detectsi fermerà non appena viene trovata la prima corrispondenza. Se stai cercando UNA partita @fathers.select {|f| f["age"] > 35 }.firstcontro @fathers.detect {|f| f["age"] > 35 } prestazioni e leggibilità, il mio voto vale perdetect
Naveed,

35

se il tuo array sembra

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

E vuoi sapere se un certo valore è già presente nel tuo array. Usa il metodo Trova

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

Questo restituirà l'oggetto se Hitesh è presente nel nome, altrimenti restituisce zero


Se il nome era minuscolo come "hitesh", non restituirà l'hash. Come possiamo tenere conto anche del casing delle parole in questi casi?
Arjun,

2
puoi usare qualcosa del genere. array.find {| x | x [: name] .downcase == "Hitesh" .downcase}
Hitesh Ranaut
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.