【Ruby】case/when構文を使った条件分岐の実装方法

みなさんこんにちは!

今回の記事は、

悩みを抱えた人
・Rubyのcase/when構文ってどうやって使うの?
・if/else構文とはどう違うの?
・case/when構文の応用テクニックが知りたい!

というお悩みを解決する記事になっています。


この記事の内容

・case/when構文の基本的な使い方
・case/when構文の基本的な実装例【コピペで試せる】
・case/when構文を使った応用テクニック【コピペで試せる】


Rubyを網羅的に学ぶならこちらがおすすめ


2022年ITエンジニア大賞を受賞した話題本



case/when構文とは?

case文は、if/else文と同様に、Rubyで分岐処理を記述するためのものです。

whenelseと併用し、1つのオブジェクトが取りうる値ごとに処理を分割するために使います。

論理値ごとに処理を分岐させたい場合など、分岐する数が少ない場合は、ifとelseを使えば十分です。

一方で、分岐する数が3つ以上に及ぶ場合は、case/when構文を使うことで、if文よりもソースコードの可読性が高い分岐処理を実装することができます。

case/when構文の使い方

早速、case/when構文の使い方について詳しく確認していきましょう。

基本的な使い方

case/when構文の基本的な使い方は以下の通りです。

case 式0
when 式1 then(※thenは省略可能です)
  # 式0と式1が一致する場合の処理を記載する
when 式2 then
  # 式0と式2の一致する場合の処理を記載する
else
  # 式1/式2のいずれとも一致しなかった場合の処理を記載する
end

実際のプログラムを見ながらの方が分かりやすいと思いますので、早速、case/when構文を使った実装例を見ていきましょう。

実装例

例として、国の名前ごとに挨拶文をコンソール上に出力するプログラムを考えてみます。

p "Please enter the country name."
country_name = gets.chomp

p country_name

case country_name
when "japan"
  p "こんにちは"
when "usa"
  p "Hello"
when "china"
  p "你好"
when "uk"
  p "Hello"
when "france"
  p "Bonjour"
when "russia"
  p "Привет"
else
  p "Please enter from japan, usa, china, uk, france, russia."
end

今回は国名を分岐条件のキーとしたいので、caseには「country_name」を設定します。

次に、when節には、caseで記述したオブジェクトが取りうる値(今回であれば6つの国名)を記載します。

また、6つの条件のいずれにも当てはまらない場合の分岐処理は、elseのあとに記述しましょう

最後にendを閉じれば、分岐処理の完成です。

なお、サンプルプログラムをif/else構文で置き換えると以下の通りになります。

# if ・ elseで記述した場合
if country_name == "japan"
  p "こんにちは"
elsif country_name == "usa"
  p "Hello"
elsif country_name == "china"
  p "你好"
elsif country_name == "uk"
  p "Hello"
elsif country_name == "france"
  p "Bonjour"
elsif country_name == "russia"
  p "Привет"
else
  p "Please enter from japan, usa, china, uk, france, russia."    
end

機能的にはcase/when構文で記述した場合と同様ですが、if文の場合は条件式として「変数 == 値」のように記述する箇所が分岐の数だけ存在してしまいます

変数を条件ごとに提示する必要があるのに対し、case/when構文を使った場合はcaseに一度記述するだけで済みます

このように、分岐数が多ければ多いほど、case/when構文を使うメリットが大きくなっていくのがお分かりいただけたかと思います。



case/when構文を使う際の応用テクニック

ここからは、case/when構文を使った応用テクニックについて、以下の4つのケースを紹介します。

  • whenに値を複数セットする
  • whenに配列をセットする
  • whenに範囲オブジェクトをセットする
  • whenに正規表現をセットする

その① when節に複数の値を設定する

when節には、一度に複数の値を複数設定することができます。

以下のサンプルコードをご覧ください。

# 都道府県を入力
prefecture_name = gets.chomp

case prefecture_name
when "tokyo"
  p "人口が1000万人以上です。"    
when "kanagawa"
  p "人口が900万人以上です。"
when "osaka"
  p "人口が800万人以上です。"
when "aichi", "saitama"
  p "人口が700万人以上です。"
when "chiba"
  p "人口が600万人以上です。"
when "hyogo", "hokkaido", "fukuoka"
  p "人口が500万人以上です。"
when "shizuoka"
  p "人口が300万人以上です。"    
else
  p "人口が300万人未満です。"
end

入力した都道府県名に対し、人口がどの程度であるかを出力するプログラムです。

100万人ごとに処理を分岐していますが、愛知県・埼玉県は人口が700万人以上、兵庫県・北海道・福岡県は人口が500万人以上で同一です。

したがって、1つの条件に複数の値を設定する必要があります。

値を複数設定する場合は、値をカンマでつなぎ合わせるように記述しましょう。

その② when節に配列を設定する

when節には、配列をセットすることも可能です。

例として、都道府県を入力した後に対応する地方を出力するプログラムを考えてみましょう。

# 都道府県を入力
prefecture_name = gets.chomp

pref_group1 = ["hokkaido", "aomori", "iwate", "miyagi", "akita", "yamagata", "fukushima"]
pref_group2 = ["tokyo", "kanagawa", "saitama", "chiba", "ibaraki", "tochigi", "gunma"]
pref_group3 = ["niigata", "toyama", "ishikawa", "fukui", "yamanashi", "nagano", "gifu", "shizuoka", "aichi"]
pref_group4 = ["mie", "shiga", "kyoto", "osaka", "hyogo", "nara", "wakayama"]
pref_group5 = ["tottori", "shimane", "okayama", "hiroshima", "yamaguchi"]
pref_group6 = ["tokushima", "kagawa", "ehime", "kochi"]
pref_group7 = ["fukuoka", "saga", "nagasaki", "oita", "miyazaki", "kumamoto", "kagoshima", "okinawa"]

case prefecture_name
when *pref_group1
  p "北海道・東北地方です。"
when *pref_group2
  p "関東地方です。"
when *pref_group3
  p "中部地方です。"
when *pref_group4
  p "近畿地方です。"
when *pref_group5
  p "中国地方です。"
when *pref_group6
  p "四国地方です。"
when *pref_group7
  p "九州・沖縄地方です。"
else
  p "日本に存在しません。"
end

地方ごとに分岐したいため、各地方に所属する都道府県を配列としてそれぞれ定義したものを用意します。

そして、when節の直後に「*配列名」の形で記述します。

なお、この部分に配列名をそのまま記載してしまうと正常に動作しませんのでご注意ください。

そのまま記述してしまうと、オブジェクトが配列と完全に一致しているか(tokushima == [“tokushima”, “kagawa”, “ehime”, “kochi”] であるか否か)を判定してしまうためです。

その③ when節に範囲オブジェクトを設定する

配列と同様に、when節に範囲オブジェクトを設定することも可能です。

age = gets.chomp.to_i

case age
when 0..5
  p "小学生未満は無料です。"
when 6..12
  p "小学生は3割引きです。"
when 13..15
  p "中学生は2割引きです。"
when 16..18
  p "高校生は1割引きです。"
when 19..65
  p "通常価格です。"
else
  p "高齢者は2割引きです。"
end

if文を使った分岐処理では不等号を使うことができますが、caseではイコール「==」による比較で固定されており、不等号が使えません

しかし、範囲オブジェクトを利用すれば、数値の範囲ごとに分岐するプログラムを実装できます。

その④ when節に正規表現を設定する

また、when節には、正規表現を設定することもできます。

input_str = gets.chomp

case input_str
when /(090|080|070)-\d{4}-\d{4}/
  p "携帯電話番号を入力しました。"
when /\d{2,5}-\d{1,4}-\d{4}/
  p "電話番号(携帯以外)を入力しました。"
when /\d{3}/
  p "特番を入力しました。"
else
  p "その他の番号です。"
end

上記では、電話番号のフォーマットごとに表示文を切り替える処理を実装しています。

最後に

本記事でご紹介した通り、case/when構文は、使い所によっては条件分岐に関する記述を大幅に短縮することが可能です。

普段はif/else文を使ってしまいがちですが、本記事の内容を踏まえて、適切な箇所でcase/when構文を使用できるようになっておきましょう。

このブログを通じて少しでも「傍(はた)を楽(らく)にする」ことができていれば嬉しく思います。

最後まで読んでいただきましてありがとうございました。

あわせて読みたい

今回は、Ruby初心者の方々に向けて、if文の基本的な使い方をご紹介していこうと思います。 「まだ勉強を始めたばかりでif文の使い方がいまいち分からない」という方も、この記事を読めばif文の使い方をバッチリ理解していただけると思いま[…]

プログラミングイメージ

Rubyを網羅的に学ぶならこちらがおすすめ


2022年ITエンジニア大賞を受賞した話題本