FizzBuzzとは
1から100の数字に対して、以下の制御を行うアルゴリズムです。
- 3で割り切れる場合は、「Fizz」と表示
- 5で割り切れる場合は、「Buzz」と表示
- 15で割り切れる場合は、「FizzBuzz」と表示
- それ以外の場合は、その数値を表示
シンプルにifを使って書くのがオーソドックスかと思います。
今回は、別解としてcaseを使って表現してみます。
まずは、結果から。
(1..100).each do |num|
puts case 0
when num % 15 then :FizzBuzz
when num % 3 then :Fizz
when num % 5 then :Buzz
else num
end
end
ポイント1:「case 式」「when 式」という構造
caseでは、「case 式」と「when 式」という形を取り、それぞれの式の結果が等しいかどうかを判定して制御を行っています。
ここで、「式」とは「num % 15」のような計算式以外にも「0」や「"AAA"」のようなオブジェクトも含まれます。
したがって、caseの隣には必ずしも「num % 15」のような計算式を、whenの隣には「0」のような値を記載するとは限りません。
case "AAA"
# whenに計算式を書くのもアリ
when "AA" + "A" then puts "same"
else puts "different"
end
# => same
上記の例では、
「"AAA" === "AA" + "A"」という比較を行った結果、等しいと判定して
「puts "same"」の処理が実行されています。
ポイント2:caseは該当のwhenに対するthen以降の値を返す
判定の結果、該当のwhen(else)のthen以降の結果をcaseの返り値として扱います。
試しに、putsをpメソッドに変えてみると、
それぞれ「:Fizz」、「:Buzz」、「:FizzBuzz」が表示されていることが確認できます。
以下の記述でも同様の結果が得られますが、少し冗長ですよね。
(1..100).each do |num|
case 0
# 判定ごとにputsを記載
when num % 15 then puts :FizzBuzz
when num % 3 then puts :Fizz
when num % 5 then puts :Buzz
else puts num
end
end
ポイント3:whenの記載順に注意!(上から順に判定)
if同様に、判定は上から順に行い、該当したところで値を返します。
したがって、仮に以下の順にした場合は、「FizzBuzz」は表示されません。
(15の倍数は先に「num % 3」に該当してしまうため「Fizz」が表示される)
(1..100).each do |num|
puts case 0
# 15の倍数はここに該当してしまう
when num % 3 then :Fizz
when num % 5 then :Buzz
when num % 15 then :FizzBuzz
else num
end
end
本記事があなたのcaseの理解に少しでも貢献できれば幸いです。