如何从嵌套循环中断到父循环,该父循环高于一级,需要嵌套循环提供的值

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

在以下情况下:

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

在确保我可以传递 true 值以便删除数组项的同时实现此多重嵌套中断的最佳方法是什么?

也许我应该使用 return true 的多个 break 语句或使用带有变量的 throw/catch ,但我不知道这些是否是最好的回答。


此题与How to break from nested loops in Ruby?不同,因为它要求父循环从嵌套循环中接收一个值。

您可以使用多个 break 语句。

例如:

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

但是,在您的特定情况下,我绝对会避免这种情况。

您不应将变量分配给 each 的结果。使用mapreduceselectrejectany?all?等代替

使用 any? 实现相同目的更有意义:

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

throw/catch(不是 raise/rescue)是我通常看到的方式。

xxx.delete_if do |x|
  catch(:done) do
    yyy.each do |y|
      zzz.each do |z|
        if x + y == z
          # Do something

          throw(:done, true)
        end
      end
    end
    false
  end
end

事实上,the Pickaxe明确推荐它:

While the exception mechanism of raise and rescue is great for abandoning execution when things go wrong, it's sometimes nice to be able to jump out of some deeply nested construct during normal processing. This is where catch and throw come in handy. When Ruby encounters a throw, it zips back up the call stack looking for a catch block with a matching symbol. When it finds it, Ruby unwinds the stack to that point and terminates the block. If the throw is called with the optional second parameter, that value is returned as the value of the catch.

也就是说,max 的 #any? 建议更适合这个问题。