Rubyで条件演算子(?:)を使用するにはどうすればよいですか?


303

? :Rubyで条件演算子()はどのように使用されますか?

たとえば、これは正しいですか?

<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>

1
はい、私はそう思いますが、次の方法でそれを達成することもできると思います。20 question=question[0,20] 未満の場合は、変更されません。
DGM 2010年

長さが20を超える場合は、「...」も追加する必要があります
Mithun Sreedharan

1
特定の列の行を盲目的に切り刻むように注意してください。途中で単語を切り取り、省略記号( '...')を追加することもできますが、これは見た目が悪いです。代わりに、近くの句読点または空白文字を探し、そこで切り捨てます。近くに良い分岐点がない場合にのみ、単語の途中を切り捨てます。
Tin Man、

回答:


496

これは三項演算子であり、Cと同様に機能します(括弧は必要ありません)。これは次のように機能する式です。

if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this

ただし、Rubyでは、優先順位の問題を除き、=== ifという式もあります。どちらも表現です。if a then b else c enda ? b : c

例:

puts (if 1 then 2 else 3 end) # => 2

puts 1 ? 2 : 3                # => 2

x = if 1 then 2 else 3 end
puts x                        # => 2

最初のケースでは括弧が必要です(それ以外の場合、Rubyはputs if 1その後に余分なジャンクがあると思われるため混乱します)が、上記の問題が発生しないため、最後のケースでは必要ありません。

複数行を読みやすくするために「long-if」フォームを使用できます。

question = if question.size > 20 then
  question.slice(0, 20) + "..."
else 
  question
end

0を置く?2:3も結果として2を返します。何故ですか?
X_Trust 14

18
@X_TrustでRubyは、唯一falsy値であるnilfalse。あまり普通ではありません。
Kroltan 2014

35
puts true ? "true" : "false"
=> "true"


puts false ? "true" : "false"
=> "false"

簡潔ですが、それが何をするかを説明します。
Tin Man

4
puts (true ? "true" : "false")括弧付きの小さな編集。それ以外の場合、操作の順序は明確ではありません。私が最初にこれを読んだときのように、私はそれを読んで、私は混乱していた (puts true) ? "true" : "false"、その後予想putsその後、文字列値になったブール値を返すように。
Fresheyeball 2015

26

ERBの使用は、あなたがRailsにいることを示唆しています。もしそうならtruncate、あなたのために仕事をする組み込みヘルパーを検討してください:

<% question = truncate(question, :length=>30) %>

これは素晴らしい!まさにやりたいこと!!
Mithun Sreedharan 2010年

11
これは数年遅れですが、すべての構文上の側面を飛び越えて、質問者が達成しようとしていたことに直結したので、私はこの回答に非常に感銘を受けました。
Mike Buckbee、2014

2
+1、ただしerbは必ずしもレールを意味するわけではありません(シナトラ、スタンドアロンERBなど)。
Fox Wilson

17

@pstは素晴らしい答えを出しましたが、Rubyでは、3項演算子は構文的に正しくなるように1行で記述されています。これは、PerlやCとは異なり、複数の行で記述できるためです。

(true) ? 1 : 0

通常、Rubyを複数行に分割しようとするとエラーが発生しますが、\行の終わりに行継続記号を使用でき、Rubyは満足します。

(true)   \
  ? 1    \
  : 0

これは単純な例ですが、コードを適切にレイアウトしておくため、長い行を処理するときに非常に役立ちます。

演算子を行の最後に置くことで、行連結文字なしで三項を使用することも可能ですが、私はそれが好きではないか、推奨しません。

(true) ?
  1 :
  0

条件テストや結果が長くなると、コードが読みにくくなると思います。

わかりにくいので三項演算子を使用しないようにとのコメントを読みましたが、それは何かを使用しないのは悪い理由です。同じロジックで、正規表現、範囲演算子( ' ..'および一見未知の "フリップフロップ"バリエーション)を使用しないでください。正しく使用すると強力なので、正しく使用する方法を学ぶ必要があります。


なぜ括弧を付けたのtrueですか?

OPの例を考えます。

<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>

条件付きテストをラップすると、テストが視覚的に分離されるため、読みやすくなります。

<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>

もちろん、ホワイトスペースの賢明な追加を使用することにより、例全体をもっと読みやすくすることができます。これはテストされていませんが、あなたはアイデアを得るでしょう:

<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
                                   : question.question 
%>

または、もっと慣用的に書かれています:

<% question = if (question.size > 20)
                question.question.slice(0, 20) + "..."
              else 
                question.question 
              end
%>

読みやすさがquestion.questionあまりにもひどいということは簡単に論じられます。


1
複数行の場合、if ... else ... endを使用しないのはなぜですか?
ウェインコンラッド

1
PerlとCでの作業が長すぎるためですか?状況に応じて、どちらか一方を使用します。一方が他方よりも視覚的に鮮明かどうかによって異なります。if / elseが冗長すぎる場合もあれば、?:が醜い場合もあります。
Tin Man、

1
@WayneConradザ・場合は、少なくとも一つの問題は、この答えで説明している:stackoverflow.com/a/4252945/2597260場合/三項演算子複数行を使用してのいくつかの方法を比較:gist.github.com/nedzadarek/0f9f99755d42bad10c30
DarekNędza

なぜ括弧を付けたのtrueですか?
Zac

1
というのtrueは、は、trueやに評価される式となるもののために実際に座っているからfalseです。3値ステートメントはすぐに視覚的なノイズに発展し、保守性に影響する可読性を低下させる可能性があるため、視覚的にそれらを区切ることをお勧めします。
Tin Man

3

オペレーターがプレイヤーのIDが1かどうかを確認し、結果に応じて敵のIDを設定する簡単な例

player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2

そして、私はかなり役立つと思われるトピックについての投稿を見つけました。


4
なんでenemy_id = player_id == 1 ? 2 : 1
アーロンブレンクシュ

1
@AaronBlenkushエレガントな入力をありがとう。私はまだnoobレベルにいます、おそらくそれが理由です:)
devwanderer 2018年


0

最も簡単な方法:

param_a = 1
param_b = 2

result = param_a === param_b ? 'Same!' : 'Not same!'

以降param_aに等しくない場合param_b、その後resultの値がされますNot same!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.