Як шукати в масиві хешів за хеш-значеннями в рубіні?


234

У мене є масив хешів, @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 

Як я можу шукати цей масив і повертати масив хешів, для яких блок повертає істину?

Наприклад:

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

Дякую.

Відповіді:


419

Ви шукаєте безліч # select (також називається find_all):

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

Згідно з документацією, він "повертає масив, що містить усі елементи [переліченого, в даному випадку @fathers], для якого блок не є хибним".


22
Ой! Ти був першим! Видалення моєї відповіді та +1.
Мілан Новота

20
Як зауваження, якщо ви хотіли знайти лише одну (першу), можете скористатися @fathers.find {|father| father["age"] > 35 }натомість.
Лі МакКаллоч

1
Чи можливо повернути індекс, де це було знайдено в початковому масиві хешей?
Ян Ворнер

1
@IanWarner Так. Я пропоную розглянути документи для модуля «Численні». Якщо ви все ще не можете зрозуміти це питання, поставте нове запитання.
Йорданія, що працює

Я щойно зробив цей індекс = ARRAY.index {| ч | h [: код] == ВІДПОВІДЬ ["код"]}
Ян Ворнер

198

це поверне перший матч

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

6
Я вважаю за краще це над #select- Але все стосується вашої справи використання. #detectповернеться, nilякщо не буде знайдено відповідності, тоді як #selectу відповідь @ Jordan повернеться [].
TJ Biddle

13
Ви також можете використовувати findзамість detectбільш читабельного коду
Alter Lagos

8
findоднак, можна заплутатися в рейках.
користувач12341234

5
selectі detectне однакові, selectперетне весь масив, а detectзупиниться, як тільки буде знайдено перший збіг. ЯКЩО ви шукаєте ОДНОГО матчу @fathers.select {|f| f["age"] > 35 }.firstпроти @fathers.detect {|f| f["age"] > 35 } продуктивності та читабельності, я голосую заdetect
Naveed

35

якщо ваш масив схожий

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

І ви хочете знати, чи якесь значення вже є у вашому масиві. Використовуйте метод пошуку

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

Це поверне об'єкт, якщо Hitesh присутній в імені, інакше повернути нуль


Якщо назва мала, як маленьке "hitesh", воно не повертає хеш. Як ми можемо обчислити словосполучення у таких випадках?
арджун

2
ви можете використовувати щось подібне. array.find {| x | x [: name] .downcase == "Hitesh" .downcase}
Hitesh Ranaut
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.