2010-03-04 2 views
97

Я что-то пропустил в документации по Array? У меня есть массив, который содержит до одного объекта, удовлетворяющего определенному критерию. Я бы хотел эффективно найти этот объект. Лучшая идея у меня из документации это:Ruby Array find_first object?

candidates = my_array.select { |e| e.satisfies_condition? } 
found_it = candidates.first if !candidates.empty? 

Но я неудовлетворен по двум причинам: (1) что выбрать меня пройти весь массив, несмотря на то, что мы могли бы выпрыгнул после первого удара, и (2) Мне нужна строка кода (с условием), чтобы сгладить кандидатов. Обе операции являются расточительными с предвидением того, что существует 0 или 1 удовлетворяющих объектов.

То, что я хотел бы что-то вроде:

array.find_first(block) -> ответы нулевой или первый объект, для которого блок истинно, окончание обхода на этом объекте.

Должен ли я написать это самостоятельно? Все эти замечательные методы в Array заставляют меня думать, что он есть, и я просто этого не вижу.

Спасибо заранее, Dan

ответ

143

Либо я не понимаю ваш вопрос, или Enumerable#find это то, что искали.

+1

Nope. Думаю, вы это поняли. Спасибо (и другим). Я не видел ни одного из методов Enumerable. Это то, что мне нужно. Извините за беспокойство. – 2010-03-04 17:24:45

+25

Нет проблем, я также часто нахожу раздражающим, что в рубиновой документации не перечислены методы всех унаследованных или включенных классов и модулей. –

+1

Дополнительная информация: '[1,2,3,5,2] .find {| n | ставит n; n == 2} 'iteration останавливается, когда находит первый элемент, который он соответствует. – rajuGT

11

Думаю, вы просто пропустили метод поиска в документации:

my_array.find {|e| e.satisfies_condition? } 
+4

Или, если вам нравится код игры в гольф, 'my_array.find (&: satisfies_condition?)' –

8

вам нужен сам объект или вам просто нужно знать, если является объект, который удовлетворяет Do. Если бывшая тогда да: использование находка:

found_object = my_array.find { |e| e.satisfies_condition? } 

иначе вы можете использовать any?

found_it = my_array.any? { |e| e.satisfies_condition? } 

Последний будет выручать с «истинным», когда он находит, что удовлетворяет условие. Бывший сделает то же самое, но вернет объект.

65

использование массива detect метод, если вы хотите, чтобы вернуть первое значение, когда блок возвращается истинный

[1,2,3,11,34].detect(&:even?) #=> 2 

OR 

[1,2,3,11,34].detect{|i| i.even?} #=> 2 

Если вы хотите, чтобы вернуть все значения, где блок возвращает верно, то использовать select

[1,2,3,11,34].select(&:even?) #=> [2, 34] 
+4

'.detect' - именно то, что мне нужно. Но какая разница с «.find»? –

+10

@AugustinRiedinger никакой разницы, оба они одинаковы. 'Detect' - просто псевдоним' find' http://ruby-doc.org/core-2.1.2/Enumerable.html#method-i-find –