user6241591 user6241591 - 3 months ago 7
Ruby Question

How to break from a nested loop to a parent loop that is more than one level above which requires a value provided by the nested loop

In the following situation:

xxx.delete_if do |x|
yyy.descend do |y| # This is a pathname.descend
zzz.each do |z|
if x + y == z
# Do something

# Break all nested loops returning to "xxx.delete_if do |x|" loop

# The "xxx.delete_if do |x|" must receive a "true" so that it
# can delete the array item
end
end
end
end


What is the best way to achieve this multiple nested break while making sure I can pass the
true
value so that the array item is deleted?

Maybe I should use multiple
break
statements that return
true
or use a
throw/catch
with a variable, but I don't know if those are the best answer.




This question is different from How to break from nested loops in Ruby? because it requires that the parent loop receives a value from the nested loop.

Answer

You can use multiple break statements.

For example:

xxx.delete_if do |x|
  result = yyy.each do |y|
    result2 = zzz.each do |z|
      if x + y == z
         break true
      end
    end
    break true if result2 == true
  end
  result == true
end

However I would definitely avoid this in your particular situation.

You shouldn't be assigning variables to the result of each. Use map, reduce, select, reject, any?, all?, etc. instead

It makes more sense to use any? to accomplish the same purpose:

xxx.delete_if do |x|
  yyy.any? do |y|
    zzz.any? do |z|
      x + y == z
    end
  end
end