Reputation: 45
I know I can write it this way successfully:
def test_find_first_multiple_of_3
numbers = [2, 8, 9, 27, 24, 5]
found = nil
numbers.each do |number|
if number % 3 == 0
found = number
break
end
end
assert_equal 9, found
end
Is there anyway to do within the block? What am I missing? Or is just not possible?
numbers.each { |n| n % 3 == 0 ? (found = n then break) : nil }
def test_find_first_multiple_of_3
numbers = [2, 8, 9, 27, 24, 5]
found = nil
numbers.each { |n| n % 3 == 0 ? (found = n then break) : nil }
assert_equal 9, found
end
Upvotes: 2
Views: 108
Reputation: 7258
As pointed by other answers, there are other ruby ways to accomplish your algorithm goal, like using the .find
method:
found = numbers.find { |n| (n % 3).zero? }
This way, you don't need to break your loop.
But, specifically answering your question, there are some ways to break the loop in the same line, if you want so:
use ;
(multiple statements separator):
numbers.each { |n| n % 3 == 0 ? (found = n; break) : nil }
or put your assigment after break, that works too:
numbers.each { |n| n % 3 == 0 ? (break found = n) : nil }
I just used your code in the example, but, again, that's not a good pratice, because, as well pointed by @the Tin Man, "hurts readability and maintenance".
Also, as pointed by @akuhn, you don't need to use ternary here. You can simply use:
numbers.each { |n| break found = n if n % 3 == 0 }
** EDITED to include suggestions from @the Tin Man, @akuhn and @Eric Duminil, in order to warn OP that there are other alternatives to run his task, that doesn't need to break loop. The original answer was written just to answer OP's question specifically (one line break loop), without the code structure concern.
Upvotes: 4
Reputation: 27793
Yes, both break
and next
take an argument.
For your example though, best use find
founds = numbers.find { |n| n % 3 == 0 }
Generally in Ruby there is rarely a reason to break
out of a loop.
You can typically use find
or any of the other functions provided by the Enumerable module, like take_while
and drop_while
…
Upvotes: 1
Reputation:
You can use the enumerable method find
to find the first item that matches. Usually you will want to use enumerable methods like cycle
, detect
, each
, reject
, and others to make the code more compact while remaining understandable:
def test_find_first_multiple_of_3
numbers = [2, 8, 9, 27, 24, 5]
found = numbers.find { |number| number % 3 == 0 }
assert_equal 9, found
end
Upvotes: 0
Reputation: 106802
With common Ruby idioms your can write:
def test_find_first_multiple_of_3
numbers = [2, 8, 9, 27, 24, 5]
found = numbers.find { |n| (n % 3).zero? }
assert_equal 9, found
end
Upvotes: 1