【Ruby】多重ループからの脱出【ネスト】


多重ループから一気に抜け出したい

Kernel.#throwKernel.#catchを使います。

sum = 0
catch(:escape_test) do
  for i in 1..3
    for j in 1..3
      sum = i + j
      # sum > 0 になった時点で一気に脱出したい
      throw(:escape_test) if sum > 0
    end
  end
end

p sum
=> 2

i = 1, j = 1の一回目の加算の段階でsum > 0の条件を満たすので、
この時点でthrow(:escape_test)が呼び出され、jのfor文iのfor文の両方から脱出します。

比較として同じロジックをbreakで使うと次のようになります。

sum = 0
for i in 1..3
  for j in 1..3
    sum = i + j
    # jのループから脱出
    break if sum > 0
  end
end

p sum
=> 4

このように、breakではもっとも内側のループ(今回はjのfor文)を脱出するので、iのfor文は回っていき、
i = 3, j = 1で処理が終了するためsum = 4となります。

おまけ:catchの戻り値

sum = 0
c_value = catch(:escape_test) do
  for i in 1..3
    for j in 1..3
      sum = i + j
      # sum > 0 になった時点で一気に脱出したい
      throw(:escape_test, sum) if sum > 0
    end
  end
end

p c_value
=> 2

このように、throwの第二引数に値を渡すとcatchの戻り値となります。

参考