🗂

三項演算子(?:)とif文の違いについて

2025/01/21に公開

状況

  • よく出てくる「?(!も出てくるがここでは省略)」について最初に理解した時から「なぜifを使わないのか」と疑問に思っていたので調べてみました。
  • 今回は三項演算子の中で使われている ? と出会ったのでそれを例に記録していく。

文の解説

status = user.active? ? "Active" : "Inactive"

この文は 三項演算子 を使った条件分岐です。三項演算子は、次の形で書かれます:

条件 ? 条件が真の場合の値 : 条件が偽の場合の値

上記の文を分解すると次のようになります:

  1. 条件

    status = user.active?
    
    • user.active が真の場合に true を返し
    • 偽の場合は false を返す
  2. 条件が真の場合の値

    "Active"
    
    • statusにActiveを代入
  3. 条件が偽の場合の値

    "Inactive"
    
    • statusにinactiveを代入

if 文で書いた場合との比較

上記の文は次のように if 文を使って書き換えることができます:

status = user.active?
  status = "Active"
else
  status = "Inactive"
end

違い

特徴 三項演算子 (? :) if 文
記述量 短く簡潔に書ける 複数行になりやすい
可読性 短い場合は読みやすいが、複雑になると読みにくい 初心者には直感的でわかりやすい
使用場面 簡単な条件分岐で適している 複雑な条件や複数の処理を含む場合に適している

なぜ三項演算子を使うのか?

  1. 値の直接代入が必要な場合

    • 三項演算子は「式」として評価されるため、直接値を代入する文脈に適しています。
    • 例:
      image = article.cover_url.present? ? (request.base_url + article.cover_url) : ""
      
      上記のように、一行で値を決定する必要がある場合、三項演算子が最適です。if 文で書くと代入が複雑になることがあります。
  2. 短く明確に条件分岐を記述したい場合

    • 条件が単純で、処理内容が簡潔な場合は、三項演算子の方が読みやすいです。
    • 例:
      status = user.active? ? "Active" : "Inactive"
      
      ここでは user.active? が真の場合に "Active" を代入し、偽の場合に "Inactive" を代入します。一行で済むため、明快です。
  3. コンパクトさが重要な場面

    • 配列やハッシュの初期化など、簡潔さが求められる場面で役立ちます。
    • 例:
      settings = { theme: user.premium? ? "dark" : "light" }
      

if 文が適している場合、または必須の場合

  1. 複雑な処理を伴う場合

    • 条件によって複数行にわたる処理が必要な場合、if 文が適しています。
    • 例:
      if user.admin?
        send_admin_email(user)
        log_admin_activity(user)
      else
        send_user_email(user)
      end
      
      三項演算子でこれを表現しようとすると、非常に読みにくくなります。
  2. 複数の条件が絡む場合

    • 条件が多岐にわたる場合や、条件がネストする場合は if 文の方が明確です。
    • 例:
      if article.cover_url.present?
        image = request.base_url + article.cover_url
      elsif article.default_image.present?
        image = article.default_image
      else
        image = "/default.jpg"
      end
      
  3. 真偽値以外の複雑な条件を扱う場合

    • 三項演算子では、条件が複雑になると可読性が低下します。
    • 例:
      if condition_one && condition_two
        do_something
      else
        do_something_else
      end
      

三項演算子 (? :) でできないこと

  • elsifelse if に相当する分岐

    • 三項演算子は基本的に「1つの条件」と「真偽値に基づく2つの結果」を扱います。複数の条件分岐が必要な場合、if 文を使うしかありません。
    • 例:
      if condition_one
        do_something
      elsif condition_two
        do_something_else
      else
        do_another_thing
      end
      
  • 複数の命令を含む場合

    • 三項演算子は1つの式として評価されるため、複数の命令を実行したい場合には向いていません。
    • NG:
      condition ? (do_something; do_something_else) : do_another_thing # エラーになる可能性
      

if 文でできないこと

  • 一行で値を決定したい場合
    • if 文は「式」ではなく「文」なので、一行での代入には向きません。
    • 例:
      # 三項演算子で簡潔に書ける
      result = condition ? "Yes" : "No"
      
      # if 文の場合、冗長になる
      if condition
        result = "Yes"
      else
        result = "No"
      end
      

まとめ

状況 三項演算子 if 文
単純な条件分岐で値を返す場合 適している 冗長になりやすい
複数行の処理を行う場合 不向き 適している
条件が複雑な場合 読みにくい 適している
一行で値を決定したい場合 必須 不向き
複数の分岐がある場合 (elsif) 不向き 必須

それぞれのメリットを理解して、適切な場面で使い分けるのがポイント

Discussion