Wie suche ich in einem Array von Hashes nach Hashwerten in Ruby?


234

Ich habe eine Reihe von 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 

Wie kann ich dieses Array durchsuchen und ein Array von Hashes zurückgeben, für die ein Block true zurückgibt?

Beispielsweise:

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

Vielen Dank.

Antworten:


419

Sie suchen nach Enumerable # select (auch genannt find_all):

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

Gemäß der Dokumentation wird "ein Array zurückgegeben, das alle Elemente von [in diesem Fall die Aufzählung @fathers] enthält, für die der Block nicht falsch ist".


22
Oh! Du warst der erste! Meine Antwort löschen und +1.
Milan Novota

20
Wenn Sie nur einen einzigen (den ersten) finden möchten, können Sie ihn @fathers.find {|father| father["age"] > 35 }stattdessen verwenden.
Leigh McCulloch

1
Ist es möglich, den Index zurückzugeben, an dem dies im ursprünglichen Array von Hashes gefunden wurde?
Ian Warner

1
@ IanWarner Ja. Ich schlage vor, die Dokumente für das Enumerable-Modul zu lesen. Wenn Sie es immer noch nicht herausfinden können, stellen Sie eine neue Frage.
Jordan läuft

Ich habe gerade diesen Index gemacht = ARRAY.index {| h | h [: code] == ARRAY ["code"]}
Ian Warner

198

Dies wird das erste Spiel zurückgeben

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

6
Ich ziehe das vor #select- aber alles gilt für Ihren Anwendungsfall. #detectwird zurückgegeben, nilwenn keine Übereinstimmung gefunden wird, während #selectin @ Jordans Antwort zurückgegeben wird [].
TJ Biddle

13
Sie können auch findanstelle detectfür einen besser lesbaren Code verwenden
Alter Lagos

8
findkann jedoch in Schienen verwirrend werden.
user12341234

5
selectund detectsind nicht gleich, selectdurchquert das gesamte Array und detectstoppt, sobald die erste Übereinstimmung gefunden wird. WENN Sie nach EINEM Spiel @fathers.select {|f| f["age"] > 35 }.firstgegen @fathers.detect {|f| f["age"] > 35 } Leistung und Lesbarkeit suchen , gilt meine Stimme fürdetect
Naveed

35

wenn Ihr Array aussieht

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

Und Sie möchten wissen, ob in Ihrem Array bereits ein Wert vorhanden ist. Verwenden Sie die Suchmethode

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

Dies gibt ein Objekt zurück, wenn Hitesh im Namen vorhanden ist, andernfalls wird nil zurückgegeben


Wenn der Name in Kleinbuchstaben geschrieben wurde "hitesh", wird der Hash nicht zurückgegeben. Wie können wir in solchen Fällen auch die Groß- und Kleinschreibung berücksichtigen?
Arjun

2
Sie können so etwas wie verwenden. array.find {| x | x [: name] .downcase == "Hitesh" .downcase}
Hitesh Ranaut
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.