Jak wyszukiwać w tablicy skrótów według wartości skrótu w Ruby?

234

Mam szereg skrótów, @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 

Jak mogę przeszukać tę tablicę i zwrócić tablicę skrótów, dla których blok zwraca wartość prawda?

Na przykład:

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

Dzięki.

doktorantange
źródło

Odpowiedzi:

419

Szukasz Enumerable # select (nazywany także find_all):

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

Zgodnie z dokumentacją „zwraca tablicę zawierającą wszystkie elementy [w tym przypadku wyliczalnego @fathers], dla których blok nie jest fałszywy”.

Jordan Running
źródło
22
O! Byłeś pierwszy! Usuwanie mojej odpowiedzi i +1.
Milan Novota
20
Uwaga: jeśli chcesz znaleźć tylko jeden (pierwszy), możesz użyć @fathers.find {|father| father["age"] > 35 }zamiast tego.
Leigh McCulloch
1
Czy jest możliwe zwrócenie indeksu miejsca, w którym został znaleziony w oryginalnej tablicy skrótów?
Ian Warner,
1
@IanWarner Tak. Sugeruję przejrzenie dokumentacji modułu Enumerable. Jeśli nadal nie możesz tego rozgryźć, opublikuj nowe pytanie.
Jordan Bieg
Właśnie zrobiłem ten indeks = ARRAY.index {| h | h [: kod] == ARRAY ["kod"]}
Ian Warner
198

to zwróci pierwszy mecz

@fathers.detect {|f| f["age"] > 35 }
Naveed
źródło
6
Wolę to niż #select- ale wszystko idzie w twoim przypadku użycia. #detectzwróci, niljeśli nie zostanie znalezione dopasowanie, a #selectw odpowiedzi @ Jordan zwróci [].
TJ Biddle
13
Możesz również użyć findzamiast detectbardziej czytelnego kodu
Alter Lagos,
8
findmoże się jednak mylić w szynach.
user12341234
5
selecti detectnie są takie same, selectprzejdą przez całą tablicę, a detectzatrzymają się, gdy tylko zostanie znalezione pierwsze dopasowanie. JEŻELI szukasz JEDNEJ meczu @fathers.select {|f| f["age"] > 35 }.firstprzeciwko @fathers.detect {|f| f["age"] > 35 } wydajności i czytelności, głosuję nadetect
Naveed,
35

jeśli twoja tablica wygląda

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

I chcesz wiedzieć, czy jakaś wartość jest już obecna w twojej tablicy. Użyj metody wyszukiwania

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

Zwróci obiekt, jeśli Hitesh jest obecny w nazwie, w przeciwnym razie zwróci zero

Hitesh Ranaut
źródło
Jeśli nazwa była mała "hitesh", nie zwróci skrótu. Jak w takich przypadkach możemy uwzględniać wielkość liter?
arjun
2
możesz użyć czegoś takiego. array.find {| x | x [: name] .downcase == "Hitesh" .downcase}
Hitesh Ranaut