在Ruby中,很容易告诉循环转到下一个项目
(1..10).each do |a|
next if a.even?
puts a
end
result =>
1
3
5
7
9
但是如果我需要从循环外部调用next(例如:method)
def my_complex_method(item)
next if item.even? # this will obviously fail
end
(1..10).each do |a|
my_complex_method(a)
puts a
end
我发现的唯一解决方案是使用throw
& catch
喜欢问题How to break outer cycle in Ruby?
def my_complex_method(item)
throw(:skip) if item.even?
end
(1..10).each do |a|
catch(:skip) do
my_complex_method(a)
puts a
end
end
我的问题是:任何人都有更复杂的解决方案吗?或throw/catch
只能这样做?
另外如果我想将my_complex_method
作为该循环的一部分(=>不要抛出:跳过),我可以以某种方式告诉我的方法它是从循环?
答案 0 :(得分:13)
你的复杂方法可以返回一个布尔值,然后你在循环上比较如下:
def my_complex_method(item)
true if item.even?
end
(1..10).each do |a|
next if my_complex_method(a)
puts a
end
一种简单的方法,但与try catch方法不同。
<强>更新强>
由于item.even?
已经返回一个布尔值,您不需要true if item.even?
部分,您可以按照以下步骤操作:
def my_complex_method(item)
item.even?
end
答案 1 :(得分:1)
Enumerator#next
和Enumerator#peek
将是goo的好选择:
def my_complex_method(e)
return if e.peek.even?
p e.peek
end
enum = (1..5).each
enum.size.times do |a|
my_complex_method(enum)
enum.next
end
<强>输出强>
1
3
5
答案 2 :(得分:0)
如果您只需要对某些值执行操作,则根据my_complex_method
返回的值,您可以明智地使用枚举器:
(1..10).map { |a| [a, my_complex_method(a)] }.each do |a, success|
puts a if success
end
<德尔>
您可以定义方法接受块,并根据成功或失败在此块中执行一些操作:
(1..10)。每个人做| a |
my_complex_method {|成功|下一次如果成功}
结束
由于范围界定,您无法使用`catch` /`throw`,并根据处理状态调用`next`。