如何打破Ruby中的嵌套循环?

crl*_*rns 50 ruby loops nested-loops

假设以下ruby代码:

bank.branches do |branch|
  branch.employees.each do |employee|
    NEXT BRANCH if employee.name = "John Doe"
  end
end
Run Code Online (Sandbox Code Playgroud)

NEXT BRANCH当然是伪代码.有没有一种方法可以打破一个父循环,例如在Perl中这样做的方式(通过使用循环标签)?

提前致谢.

ste*_*lag 91

Catch and throw可能是您正在寻找的:

bank.branches do |branch|
  catch :missingyear do  #:missingyear acts as a label
    branch.employees.each do |employee|
      (2000..2011).each do |year|
        throw :missingyear unless something  #break out of two loops
      end
    end
  end #You end up here if :missingyear is thrown
end
Run Code Online (Sandbox Code Playgroud)

  • 为了正确性,`catch`和`throw`不是Ruby中的错误.Ruby有'raise`和`rescue`来捕获错误.catch和throw实际上只是为了摆脱上下文.就像其他语言中的`goto`一样. (28认同)
  • 不是真的,`扔:球; catch:ball`导致错误. (4认同)

Chu*_*uck 16

没有他们的同意,没有内置的方法来打破包含块.你只需要做以下事情:

bank.branches do |branch|
  break unless branch.employees.each do |employee|
    break if employee.name == "John Doe"
  end
end
Run Code Online (Sandbox Code Playgroud)


Ann*_*001 7

while c1
 while c2
    # execute code
    do_break = true if need_to_break_out_of_parent_loop
 end
 break if do_break
end
Run Code Online (Sandbox Code Playgroud)


Sto*_*vey 5

我的冲动是将嵌套块移动到一个方法中,用 areturn代替break.

def find_branch_and_employee_by_name(bank,emp_name)
  bank.branches.each do |branch|
    branch.employees.each do |employee|
      return([branch,employee]) if employee.name == emp_name
    end
  end
  nil   # employee wasn't found
end
Run Code Online (Sandbox Code Playgroud)