初めに
paizaで競プロみたいなことできるやん!!ってなってとりあえず朝の勉強初めはやる気出すために遊んでいるのですが。
その中でreturn等、処理を終わらせる記述の挙動についてわかってなかったな〜ってことがあったので書き留めておきます(正直まだ理解しきってはいない)
環境
Ruby 2.6.5
遭遇したこと
以下の様なコードを書いていました。(数値とかは問題の公表につながらない様書き換えています)
array = [1,2,3]
ans = []
array.each do |a|
if a >= 1
ans << a
return
end
end
p ans
簡略化した処理をしていますが、僕がやりたかったのは以下の様なことでした。
配列の要素について条件を検証し、該当するものが見つかった時点でその値を空配列に入れ、繰り返し処理を終える
上記のコードで言えば一番目の1の時点でifに該当しているので、ans = [1]となり処理が終わってくれれば良いのでした。
そして上記コードを実行した結果が以下の通り。
何も反応しねえ。
何もpされてこない訳です。
僕は最初これを、ansにaが入っていないから表示されていないと思い、returnでスコープが変わる・・・!?とか動揺してたんですが。
よく考えたらその場合でも p ansしたら []って感じで空の配列は表示されるはずなんですよね。
そう思って上記コードの最後に 「p array」と追記しても何も表示されなかったので、「ああーー処理が終わってんのか!」とたどり着くことができた訳です。
上記の様なケースに遭遇したため、処理を終わらせる方法について調べて出てきた3つについてまとめておこうと思います(return,break,next)
returnについて
returnはメソッドそのものを終わらせます
上記が答えです。
それについては知っていたのですが、今回の場合defでメソッドを作っていた訳じゃないので以降の処理が終了するという状況が同じであると気付けませんでした。
ここ、正直あやふやですが、今回の様に何も定義しないでやってる場合は「そのプログラム全体を範囲として終了させる」ということでしょうか。
ちなみにメソッドを終わらせるとはどういうことか例を使ってもう少し説明すると
array = [1,2,3]
ans = []
def check
array.each do |a|
if a >= 1
ans << a
return
end
puts "Hello"
end
上記の様なケースでcheckメソッドを実行した場合、returnが終わらせるのはeach処理ではなくcheck全てです。
なので、returnでeachの処理が終わった後、puts "Hello"されるわけではありません、ということです。
何か処理の中で使われていても、その処理だけを終わらせるのではなく、メソッドそのものを終わらせるのがreturn ですよ、ということですね。
breakについて
breakはその繰り返し処理のみを終わらせます。
今回の場合これが僕のやりたかったことですね。
array = [1,2,3]
ans = []
array.each do |a|
if a >= 1
ans << a
break
end
end
p ans
望んでいた[1]がえられました。
条件に該当した時点で、each処理のみを終わらせてくれた、という期待していた挙動になっています。
nextについて
実行されてる処理内で、以降の処理を行わず終わらせますが、繰り返し処理自体は続きます
ちょっとわかりづらいので、以下の様にコードを書き換えて実験して見ます。
array = [3,2,1]
ans = []
sum = 0
array.each do |a|
if a >= 2
ans << a
end
sum += 1
end
p sum
if内の条件をa >= 2にしたので、array[2]は1であるためそれのみ条件に非該当になります。
カウンター用にsumを用意しました。
これを実行すると以下の結果になります。
sum += 1はif外かつeach内の処理なので、ifに該当してようとしてなかろうと、要素の数だけ繰り替えされます。
今回は要素が3個あるので、「3」と出力されるわけです。
これにnextを追記します。
array = [3,2,1]
ans = []
sum = 0
array.each do |a|
if a >= 2
ans << a
next
end
sum += 1
end
p sum
結果は以下の通りです。
ifに該当した場合、nextによって以降の処理を無視します。
なので3、2の場合はsum += 1が行われません。
ただし、繰り返し処理自体は継続されます。
なので、array[2]が1であり、ifに非該当であった場合はsum += 1が実行されており、結果として1が出力されているわけです。
終わりに
頭でわかってることをプログラムにやってもらう時の指示の出し方についてまだまだ知らないことが多いな〜という印象です。
機械語を理解するのは大事だなと思うわけで、半分趣味にはなってますがアルゴリズムの勉強もしたくてたまんないなという最近です。実際こういう気づきあるし笑
※かなりざっくりした理解で書いているので、間違い等あれば指摘いただけるとありがたいです。