从外部方法调用ruby循环上的next

时间:2013-07-09 10:59:14

标签: ruby

在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作为该循环的一部分(=>不要抛出:跳过),我可以以某种方式告诉我的方法它是从循环?

3 个答案:

答案 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#nextEnumerator#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`。