回答:
case x
when 1..5
"It's between 1 and 5"
when 6
"It's 6"
when "foo", "bar"
"It's either foo or bar"
when String
"You passed a string"
else
"You gave me #{x} -- I have no idea what to do with that."
end
Ruby は、演算子を使用when
して、case
句のオブジェクトを句のオブジェクトと比較します===
。たとえば、1..5 === x
ではなくx === 1..5
です。
これにより、when
上記のように高度な句を使用できます。範囲、クラス、およびあらゆる種類のものを、単なる等価ではなくテストできます。
異なり、switch
他の多くの言語でのステートメント、Rubyのはcase
持っていないフォールスルーので、各終了する必要はありません、when
とはbreak
。のwhen
ように、1つの句で複数の一致を指定することもできますwhen "foo", "bar"
。
when
し、return
同じ行にステートメントを:when "foo" then "bar"
then
。他の回答もご覧ください。
case...when
クラスを処理するときに、少し予期せず動作します。これは、===
演算子を使用しているためです。
その演算子は、リテラルでは期待どおりに機能しますが、クラスでは機能しません。
1 === 1 # => true
Fixnum === Fixnum # => false
つまりcase ... when
、オブジェクトのクラスに対してaを実行する場合、これは機能しません。
obj = 'hello'
case obj.class
when String
print('It is a string')
when Fixnum
print('It is a number')
else
print('It is not a string or number')
end
「文字列または数値ではありません」と出力します。
幸い、これは簡単に解決できます。===
オペレータは、それが返すように定義されているtrue
あなたは、クラスでそれを使用し、第二オペランドとして、そのクラスのインスタンスを指定した場合:
Fixnum === 1 # => true
つまり、上記のコードは次のコードを削除することで修正できます.class
。
obj = 'hello'
case obj # was case obj.class
when String
print('It is a string')
when Fixnum
print('It is a number')
else
print('It is not a string or number')
end
今日、答えを探しながらこの問題にぶつかりました。これが最初に表示されたページだったので、同じ状況にいる他の人に役立つと思いました。
.class
に参加して、おかげで注意することは興味深いです。もちろん、これは完全に適切な動作です(それがprintだと考えるのがよくある間違いであることがわかりましたがIt is a string
)... オブジェクト自体ではなく、任意のオブジェクトのクラスをテストしています。したがって、たとえば、case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end
結果は次のようになります。"Class!"
これは、、などでも同じよう1.class
に機能{}.class
します。ドロップすると.class
、これらのさまざまな値に対して"String!"
または"Something else"
が取得されます。
case
Rubyで使っています。Wikipediaの「Switchステートメント」も参照してください。
引用:
case n
when 0
puts 'You typed zero'
when 1, 9
puts 'n is a perfect square'
when 2
puts 'n is a prime number'
puts 'n is an even number'
when 3, 5, 7
puts 'n is a prime number'
when 4, 6, 8
puts 'n is an even number'
else
puts 'Only single-digit numbers are allowed'
end
もう一つの例:
score = 70
result = case score
when 0..40 then "Fail"
when 41..60 then "Pass"
when 61..70 then "Pass with Merit"
when 71..100 then "Pass with Distinction"
else "Invalid Score"
end
puts result
Kindle のRubyプログラミング言語(第1版、O'Reilly)の約123ページでthen
、when
節に続くキーワードは改行またはセミコロンで置き換えることができると書かれています(if then else
構文のように)。(Ruby 1.8では、の代わりにコロンも使用できthen
ますが、この構文はRuby 1.9 では使用できなくなりました。)
when (-1.0/0.0)..-1 then "Epic fail"
type = #{score}
各行を言うのではなく、単にあなたがしたことをコピーできます。はるかにエレガントな私はまた、可能な場合はワンライナーがはるかに良い
チャックの答えにさらに例を追加するには:
パラメータあり:
case a
when 1
puts "Single value"
when 2, 3
puts "One of comma-separated values"
when 4..6
puts "One of 4, 5, 6"
when 7...9
puts "One of 7, 8, but not 9"
else
puts "Any other thing"
end
パラメータなし:
case
when b < 3
puts "Little than 3"
when b == 3
puts "Equal to 3"
when (1..10) === b
puts "Something in closed range of [1..10]"
end
kikitoが警告する「Rubyでswitch文を書く方法」に注意してください。
or
多くのプログラミング言語、特にCから派生したものは、いわゆるSwitch Fallthroughをサポートしています。私はRubyで同じことをするための最良の方法を探していて、それが他の人に役立つかもしれないと思いました:
Cのような言語では、フォールスルーは通常次のようになります。
switch (expression) {
case 'a':
case 'b':
case 'c':
// Do something for a, b or c
break;
case 'd':
case 'e':
// Do something else for d or e
break;
}
Rubyでは、同じことを次の方法で実現できます。
case expression
when 'a', 'b', 'c'
# Do something for a, b or c
when 'd', 'e'
# Do something else for d or e
end
これは厳密には同等ではありません。'a'
コードブロックを実行する前に、'b'
または'c'
に進むことができないためですが、ほとんどの場合、同じように使用できるほど十分に似ています。
Ruby 2.0では、case
次のようにステートメントでラムダを使用することもできます。
is_even = ->(x) { x % 2 == 0 }
case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end
カスタムのStructを使用して、独自のコンパレータを簡単に作成することもできます ===
Moddable = Struct.new(:n) do
def ===(numeric)
numeric % n == 0
end
end
mod4 = Moddable.new(4)
mod3 = Moddable.new(3)
case number
when mod4 then puts 'multiple of 4'
when mod3 then puts 'multiple of 3'
end
(「Ruby 2.0のケースステートメントでプロシージャを使用できますか?」からの例)
または、完全なクラスで:
class Vehicle
def ===(another_vehicle)
self.number_of_wheels == another_vehicle.number_of_wheels
end
end
four_wheeler = Vehicle.new 4
two_wheeler = Vehicle.new 2
case vehicle
when two_wheeler
puts 'two wheeler'
when four_wheeler
puts 'four wheeler'
end
文字列のタイプの検索など、正規表現を使用できます。
case foo
when /^(true|false)$/
puts "Given string is boolean"
when /^[0-9]+$/
puts "Given string is integer"
when /^[0-9\.]+$/
puts "Given string is float"
else
puts "Given string is probably string"
end
Ruby はこれにcase
等価オペランド===
を使用します(@JimDevilleに感謝)。詳細については、「Rubyオペレーター」を参照してください。これは、@ mmdemirbasの例(パラメーターなし)を使用して行うこともできます。このアプローチのみが、これらのタイプのケースに適しています。
RubyのスイッチケースでOR条件を使用する方法を知りたい場合:
だから、中にcase
声明、,
のと同じです||
でif
声明。
case car
when 'Maruti', 'Hyundai'
# Code here
end
「RubyのCaseステートメントの仕組みとそれを使ってできること」を参照してください。
それは呼び出されcase
、期待どおりに機能します。さらに===
、テストを実装する多くの楽しい機能を提供しています。
case 5
when 5
puts 'yes'
else
puts 'else'
end
楽しみにしてください:
case 5 # every selector below would fire (if first)
when 3..7 # OK, this is nice
when 3,4,5,6 # also nice
when Fixnum # or
when Integer # or
when Numeric # or
when Comparable # (?!) or
when Object # (duhh) or
when Kernel # (?!) or
when BasicObject # (enough already)
...
end
また、任意のif / elseチェーン(つまり、テストに共通変数が含まれていない場合でも)をcase
、初期case
パラメーターを省略して、最初の一致が必要な式を記述するだけで置き換えることもできることがわかりました。
case
when x.nil?
...
when (x.match /'^fn'/)
...
when (x.include? 'substring')
...
when x.gsub('o', 'z') == 'fnzrq'
...
when Time.now.tuesday?
...
end
Rubyはcase
switchステートメントの記述にを使用します。
case
ドキュメントに従って:
Caseステートメントは、への引数の位置にあるオプションの条件
case
と、0個以上のwhen
句で構成されます。when
条件に一致する最初の句(または、条件がnullの場合はブール値の真と評価される)が「優先」され、そのコードスタンザが実行されます。caseステートメントの値は、成功したwhen
句の値かnil
、そのような句がない場合です。caseステートメントは
else
句で終了できます。各when
ステートメントは、カンマで区切られた複数の候補値を持つことができます。
例:
case x
when 1,2,3
puts "1, 2, or 3"
when 10
puts "10"
else
puts "Some other number"
end
短いバージョン:
case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end
そして「Rubyのケースステートメント-高度なテクニック」がRubyを説明するようにcase
;
case 5
when (1..10)
puts "case statements match inclusion in a range"
end
## => "case statements match inclusion in a range"
Regexで使用できます。
case "FOOBAR"
when /BAR$/
puts "they can match regular expressions!"
end
## => "they can match regular expressions!"
ProcsおよびLambdasで使用できます。
case 40
when -> (n) { n.to_s == "40" }
puts "lambdas!"
end
## => "lambdas"
また、独自のマッチクラスで使用できます:
class Success
def self.===(item)
item.status >= 200 && item.status < 300
end
end
class Empty
def self.===(item)
item.response_size == 0
end
end
case http_response
when Empty
puts "response was empty"
when Success
puts "response was a success"
end
場合によっては、メソッドのハッシュを使用することもできます。
when
sの長いリストがあり、それらのそれぞれが(間隔ではなく)比較する具体的な値を持っている場合、メソッドのハッシュを宣言してから、そのようなハッシュから関連するメソッドを呼び出すほうが効果的です。
# Define the hash
menu = {a: :menu1, b: :menu2, c: :menu2, d: :menu3}
# Define the methods
def menu1
puts 'menu 1'
end
def menu2
puts 'menu 2'
end
def menu3
puts 'menu3'
end
# Let's say we case by selected_menu = :a
selected_menu = :a
# Then just call the relevant method from the hash
send(menu[selected_menu])
以来switch case
、常に単一のオブジェクトを返す、我々は直接、その結果を印刷することができます。
puts case a
when 0
"It's zero"
when 1
"It's one"
end
多値の場合と無値の場合:
print "Enter your grade: "
grade = gets.chomp
case grade
when "A", "B"
puts 'You pretty smart!'
when "C", "D"
puts 'You pretty dumb!!'
else
puts "You can't even use a computer!"
end
そして、ここでの正規表現ソリューション:
print "Enter a string: "
some_string = gets.chomp
case
when some_string.match(/\d/)
puts 'String has numbers'
when some_string.match(/[a-zA-Z]/)
puts 'String has letters'
else
puts 'String has no numbers or letters'
end
case some_string, when /\d/, (stuff), when /[a-zA-Z]/, (stuff), end
で,
はない(どこで改行を意味する)
case
Rubyでは2つの異なる方法で式を記述できます。
if
ステートメントに似ていますcase
と、各when
句がターゲットと比較されます。age = 20
case
when age >= 21
puts "display something"
when 1 == 0
puts "omg"
else
puts "default condition"
end
または:
case params[:unknown]
when /Something/ then 'Nothing'
when /Something else/ then 'I dont know'
end
素晴らしい答えはたくさんありますが、1つのfactoidを追加したいと思いました。
「Rubyの平等とオブジェクトの比較」は、このトピックに関する良い議論です。
<=>
であり、比較がそれぞれ「より小さい」、「等しい」、「より大きい」、または「比較できない」を返すかどうかに応じて、-1、0、1、またはnilを返すために使用されます。RubyのComparableモジュールのドキュメントで説明しています。
上記の回答の多くで述べたように、===
演算子はcase
/ when
ステートメントの内部で使用されます。
その演算子に関する追加情報を次に示します。
===
Rubyの組み込みクラスの多く(String、Range、Regexpなど)は、===
「case-equality」、「triple equals」、「threequals」とも呼ばれる独自の演算子の実装を提供します。クラスごとに実装が異なるため、呼び出されたオブジェクトのタイプによって動作が異なります。通常、右側のオブジェクトが左側のオブジェクトに「属している」または「のメンバーである」場合、trueを返します。たとえば、オブジェクトがクラス(またはそのサブクラスの1つ)のインスタンスであるかどうかをテストするために使用できます。
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
同じ結果は、次のような、おそらく最高の仕事に適している他の方法により達成することができますis_a?
とinstance_of?
。
===
ときに===
オペレータが範囲オブジェクトに対して呼び出され、右側の値は、左の範囲内にある場合、それは真を返します。
(1..4) === 3 # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6 # Output: => false
("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false
===
オペレーターは===
左側のオブジェクトのメソッドを呼び出すことに注意してください。したがって、(1..4) === 3
と同等(1..4).=== 3
です。言い換えると、左側のオペランドのクラスは、===
呼び出されるメソッドの実装を定義するため、オペランドの位置は交換できません。
===
右側の文字列が左側の正規表現と一致する場合はtrueを返します。
/zen/ === "practice zazen today" # Output: => true
# is similar to
"practice zazen today"=~ /zen/
上記の2つの例の唯一の関連する違いは、一致がある場合に===
trueを=~
返し、Rubyでは真の値である整数を返すことです。これはすぐに戻ります。
puts "Recommend me a language to learn?"
input = gets.chomp.downcase.to_s
case input
when 'ruby'
puts "Learn Ruby"
when 'python'
puts "Learn Python"
when 'java'
puts "Learn Java"
when 'php'
puts "Learn PHP"
else
"Go to Sleep!"
end
$age = 5
case $age
when 0 .. 2
puts "baby"
when 3 .. 6
puts "little child"
when 7 .. 12
puts "child"
when 13 .. 18
puts "youth"
else
puts "adult"
end
詳細については、「Ruby-if ... else、case、notif」を参照してください。
ご使用の環境では正規表現はサポートされていませんか?例:Shopifyスクリプトエディター(2018年4月):
[エラー]:初期化されていない定数RegExp
こことここですでにカバーされている方法の組み合わせに続く回避策:
code = '!ADD-SUPER-BONUS!'
class StrContains
def self.===(item)
item.include? 'SUPER' or item.include? 'MEGA' or\
item.include? 'MINI' or item.include? 'UBER'
end
end
case code.upcase
when '12345PROMO', 'CODE-007', StrContains
puts "Code #{code} is a discount code!"
when '!ADD-BONUS!'
puts 'This is a bonus code!'
else
puts 'Sorry, we can\'t do anything with the code you added...'
end
よりも優先順位が高い
or
ため、クラスメソッドステートメントでs を使用しました。もしあなたがルビーナチなら、代わりにこれを使ったと想像してください。repl.itテスト。||
.include?
(item.include? 'A') || ...
句,
ではコンマ()を強調することが重要when
です。これ||
は、if
ステートメントのとして機能します。つまり、句の区切られた式間のAND比較ではなく、OR比較を実行します。次のcaseステートメントを参照してください。when
x = 3
case x
when 3, x < 2 then 'apple'
when 3, x > 2 then 'orange'
end
=> "apple"
x
は2以上ですが、戻り値は"apple"
です。どうして?そのためx
3および以来だっ',`` acts as an
|| , it did not bother to evaluate the expression
x <2 '。
ANDを実行するには、以下のようにすることができますが、機能しません。
case x
when (3 && x < 2) then 'apple'
when (3 && x > 2) then 'orange'
end
=> nil
これは、理由は動作しません(3 && x > 2)
Trueに評価し、そしてRubyは真の値を取り、それを比較x
して===
いるので、真されていない、x
3です。
&&
比較を行うにはcase
、if
/ else
ブロックのように扱う必要があります。
case
when x == 3 && x < 2 then 'apple'
when x == 3 && x > 2 then 'orange'
end
Rubyプログラミング言語の本では、マッツは、この後者の形式は用の代替構文以外の何ものでもありません、単純な(そしてあまり使われない)形態であると言いますif
/ elsif
/ else
。ただし、使用頻度が低いかどうかに関係なく&&
、特定のwhen
句に複数の式をアタッチする他の方法はありません。
if...elsif
か?Caseステートメントと条件を混在させようとしているようです。どうして?whenブロックの中に条件を置くだけです。when 3; ( x < 2 ) ? 'apple' : 'orange'
複数の条件のswitchステートメントを書くことができます。
例えば、
x = 22
CASE x
WHEN 0..14 THEN puts "#{x} is less than 15"
WHEN 15 THEN puts "#{x} equals 15"
WHEN 15 THEN puts "#{x} equals 15"
WHEN 15..20 THEN puts "#{x} is greater than 15"
ELSE puts "Not in the range, value #{x} "
END
case
、when
、end
)大文字と小文字が区別され、次のように大文字にすることはできません。
NoMethodError (undefined method
CASE 'for main:Object) `。@ sondra.kinseyが言ったように、大文字は使用できません。Rubyはそれを定数だと考えます。
case
声明演算子は似ているswitch
他の言語インチ
これはswitch...case
C の構文です:
switch (expression)
{
case constant1:
// statements
break;
case constant2:
// statements
break;
.
.
.
default:
// default statements
}
case...when
Ruby の構文は次のとおりです。
case expression
when constant1, constant2 #Each when statement can have multiple candidate values, separated by commas.
# statements
next # is like continue in other languages
when constant3
# statements
exit # exit is like break in other languages
.
.
.
else
# statements
end
例えば:
x = 10
case x
when 1,2,3
puts "1, 2, or 3"
exit
when 10
puts "10" # it will stop here and execute that line
exit # then it'll exit
else
puts "Some other number"
end
詳細については、 case
ドキュメントを。