开发者

In Ruby, is there a method similar to `any?` which returns the matching item (rather than `true`)

开发者 https://www.devze.com 2023-04-12 22:29 出处:网络
>> [1, 2, 3, 4, 5].any? {开发者_StackOverflow社区|n| n % 3 == 0} => true What if I want to know which item matched, not just whether an item matched? I\'m only interested in short-circuitin
>> [1, 2, 3, 4, 5].any? {开发者_StackOverflow社区|n| n % 3 == 0}
=> true

What if I want to know which item matched, not just whether an item matched? I'm only interested in short-circuiting solutions (those that stop iterating as soon as a match is found).

I know that I can do the following, but as I'm new to Ruby I'm keen to learn other options.

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


Are you looking for this:

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

From the docs:

Passes each entry in enum to block. Returns the first for which block is not false.

So this would also fulfill your 'short-circuiting' requirement. Another, probably less common used alias for Enumerable#find is Enumerable#detect, it works exactly the same way.


If you want the first element for which your block is truthy, use detect:

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

If you want the index of the first element that matches, use find_index:

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

If you want all elements that match, use select (this does not short-circuit):

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


If you want short circuiting behavior, you want Enumerable#find, not select

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] 
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号