В Ruby есть метод, похожий на `any?", Который возвращает соответствующий элемент (а не "true") - PullRequest
3 голосов
/ 12 октября 2011
>> [1, 2, 3, 4, 5].any? {|n| n % 3 == 0}
=> true

Что, если я хочу знать , какой элемент соответствует, а не просто соответствует ли элемент? Меня интересуют только решения с коротким замыканием (те, которые прерывают итерации, как только найдено совпадение).

Я знаю, что могу сделать следующее, но, поскольку я новичок в Ruby, я стремлюсь изучить другие варианты.

>> match = nil
=> nil
>> [1, 2, 3, 4, 5].each do |n|
..   if n % 3 == 0
..     match = n
..     break
..   end
.. end
=> nil
>> match
=> 3

Ответы [ 3 ]

6 голосов
/ 12 октября 2011

Вы ищете это:

[1, 2, 3, 4, 5].find {|n| n % 3 == 0} # => 3

Из документов :

Пропускает каждую запись в enum для блокировки. Возвращает первое, для которого блок не равен false.

Так что это также удовлетворяет вашему требованию «короткого замыкания». Другой, вероятно, менее распространенный псевдоним для Enumerable#find - Enumerable#detect, он работает точно так же.

5 голосов
/ 12 октября 2011

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

[1, 2, 3, 4, 5].detect {|n| n % 3 == 0}
# => 3

Если вы хотите, чтобы индекс первого элемента соответствовал, используйте find_index:

[1, 2, 3, 4, 5].find_index {|n| n % 3 == 0}
# => 2

Если вы хотите, чтобы все совпадали элементы, используйте select (это не приводит к короткому замыканию):

[1, 2, 3, 4, 5, 6].select {|n| n % 3 == 0}
# => [3, 6]
3 голосов
/ 12 октября 2011

Если вы хотите использовать короткое замыкание, вы хотите, чтобы Enumerable # находил, а не выбирал

ruby-1.9.2-p136 :004 > [1, 2, 3, 4, 5, 6].find  {|n| n % 3 == 0}
 => 3 
ruby-1.9.2-p136 :005 > [1, 2, 3, 4, 5, 6].select  {|n| n % 3 == 0}
 => [3, 6] 
...