假设以下ruby代码:
bank.branches do |branch|
branch.employees.each do |employee|
NEXT BRANCH if employee.name = "John Doe"
end
end
NEXT BRANCH当然是伪代码。有没有一种方法可以突破父循环,例如Perl中的方式(通过使用循环标签)?
提前感谢。
答案 0 :(得分:84)
Catch 和 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
答案 1 :(得分:16)
没有他们的同意,没有内置的方法来打破包含块。你只需要做一些事情:
bank.branches do |branch|
break unless branch.employees.each do |employee|
break if employee.name == "John Doe"
end
end
答案 2 :(得分:5)
while c1
while c2
# execute code
do_break = true if need_to_break_out_of_parent_loop
end
break if do_break
end
答案 3 :(得分:4)
我的冲动是将嵌套的块移动到一个方法中,用return
代替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
答案 4 :(得分:0)
修改强> 通过调用内部循环中的break(只会终止该循环),可以更简单地实现所需的效果:
bank.branches do |branch|
branch.employees.each do |employee|
break if employee.name = "John Doe"
end
end
以下是 @steenslag 使用Ruby begin-rescue-end块编写的内容:
letters = [%w(a b c),%w(d e f),%w(g h i)]
# => [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]
letters.each do |trine|
begin
trine.each do |letter|
raise "Breaking out of inner cycle." if letter == "e"
puts letter
end
rescue
next
end
end
# => abcdghi
所以你的例子是:
bank.branches do |branch|
branch.employees.each do |employee|
begin
raise "Breaking out of inner cycle." if employee.name = "John Doe"
rescue
next
end
end
end
答案 5 :(得分:0)
其他帖子引用了类似于创建“switch”变量的想法。请参阅下文,了解其工作原理的明确示例。请记住,第二个循环仍将一直运行,直到它到达employee数组的末尾,但在切换开关后不会执行任何代码。这不是执行此操作的最佳方式,因为如果您的员工阵列很大,则可能会花费不必要的时间。
def workforce
bank.branches do |branch|
switch = 0
branch.employees.each do |employee|
if switch == 1
next
end
if employee.name = "John Doe"
switch = 1
end
end
end
在翻转开关后,内部阵列将不再处于活动状态,并且父循环将在切换复位时移动到下一个分支。显然,更多的开关可以用于更复杂的情况。