Rubyでswitch文を書くにはどうすればいいですか?
Rubyは case
式 を代わりに使用します。
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
は fall-through を持たないので、それぞれのwhen
をbreak
で終わらせる必要はありません。 when "foo", "bar"
のように、1つのwhen
句に複数の一致を指定することもできます。
case...when
は、クラスを処理するときに少し予期しない動作をします。これは===
演算子を使用しているためです。
この演算子はリテラルでは期待どおりに機能しますが、クラスでは機能しません。
1 === 1 # => true
Fixnum === Fixnum # => false
つまり、オブジェクトのクラスに対してcase ... when
を実行したい場合、これは機能しません。
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')
end
「それは文字列ではありません」と表示します。
幸い、これは簡単に解決できます。 ===
演算子は、クラスとともに使用し、そのクラスのインスタンスを2番目のオペランドとして指定した場合に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')
end
私は答えを探している間今日この問題にぶつかりました、そして、これは最初に現れるページでした、それで私はそれが私の同じ状況で他の人に役に立つだろうと考えました。
Rubyでは case によって行われます。 Wikipediaに関するこの記事 も参照してください。
引用:
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
The Ruby Programming Lanugage (第1版、O'Reilly)の123ページ周辺(私はKindleを使用しています)では、then
句に続くwhen
キーワードを改行またはセミコロンで置き換えることができます(ちょうど同じ) if then else
構文にあります。 (Ruby 1.8ではthen
..の代わりにコロンを使用することもできます。しかし、この構文はRuby 1.9では使用できなくなりました。)
Chuck's answer に例を追加するには:
パラメータ付き:
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
問題 - キキトが警告していることに注意してください。
多くのプログラミング言語、特に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ではcaseステートメントでprocを使うことができますか? "からの例です。)
あるいは、完全なクラスでは:
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
( " Ruby Caseステートメントのしくみとあなたができること "からの例)
文字列の種類を見つけるなどの正規表現を使用できます。
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 Operators "にあります。これは@mmdemirbasの例を使用して(パラメータなしで)実行することもできますが、このような場合にはこのアプローチのみがよりクリーンです。
RubyのスイッチケースでOR条件を使用する方法を知りたければ、
したがって、case
ステートメントでは、,
はif
ステートメントの||
と同等です。
case car
when 'Maruti', 'Hyundai'
# Code here
end
これは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
最初のcase
パラメータを省略し、最初の一致があなたのものである式を書くだけで、任意のif/elseチェーン(つまりテストが共通変数を含まない場合でも)をcase
に置き換えることもできます。欲しいです。
case
when x.nil?
...
when (x.match /'^fn'/)
...
when (x.include? 'substring')
...
when x.gsub('o', 'z') == 'fnzrq'
...
when Time.now.tuesday?
...
end
あなたのケースに応じて、あなたはメソッドのハッシュを使うことを好むかもしれません。
Whenの長いリストがあり、それぞれが(区間ではなく)比較するための具体的な値を持っている場合、メソッドのハッシュを宣言してからそのようなハッシュから関連するメソッドを呼び出す方が効果的です。
# 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])
複数値の場合と値なしの場合
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
switch case
は常に単一のオブジェクトを返すので、その結果を直接出力することができます。
puts case a
when 0
"It's zero"
when 1
"It's one"
end
Rubyはswitch文を書くためにcase
を使います。
Ruby Docs に従って:
Caseステートメントは、
case
への引数の位置にあるオプションの条件、および0個以上のwhen
句で構成されます。条件に一致する(または条件がnullの場合はブール値の真理値に評価される)最初のwhen
節が「勝ち」、そのコードスタンザが実行されます。 case文の値は、成功したwhen
句の値、またはそのような句がない場合はnil
の値です。Case文は
else
句で終わることができます。各when
aステートメントは、コンマで区切られた複数の候補値を持つことができます。
例:
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
そしてこのブログのように Honeybadger はRuby Caseについて説明します。
範囲 と共に使用できます。
case 5
when (1..10)
puts "case statements match inclusion in a range"
end
## => "case statements match inclusion in a range"
正規表現 と共に使用できます。
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
Rubyでは2つの異なる方法でcase式を書くことができます。
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
もっと自然な方法でこうすることができます、
case expression
when condtion1
function
when condition2
function
else
function
end
たくさんの素晴らしい答えがありますが、私は1つのファクトイドを追加したいと思いました。
これはトピックについてのよい議論です http://www.skorks.com/2009/09/Ruby-equality-and-object-comparison/ /
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
上記の回答の多くで述べられているように、===演算子はcase/whenステートメントの裏で使われています。
これはその演算子に関するいくつかの追加情報です。
String、Range、RegexpなどのRubyの組み込みクラスの多くは、独自の===演算子の実装を提供します。これらは、大文字小文字の区別、三重等号または三重等号とも呼ばれます。各クラスで実装が異なるため、呼び出されたオブジェクトの種類によって動作が異なります。一般に、右側のオブジェクトが左側のオブジェクトの「に属している」または「のメンバー」である場合は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?。
範囲オブジェクトに対して===演算子が呼び出されると、右側の値が左側の範囲内にある場合にtrueが返されます。
(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/=== "今日のzazenの練習"#出力:=> true#は "今日のzazenの練習"に似ています=〜/ zen /
上記2つの例の唯一の関連する違いは、一致があるとき===がtrueを返し、=〜が整数を返すということです。これはRubyでは真の値です。まもなくこれに戻ります。
$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
reference => https://www.tutorialspoint.com/Ruby/ruby_if_else.htm
複数の条件に対して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
私は使い始めました:
a = "secondcase"
var_name = case a
when "firstcase" then "foo"
when "secondcase" then "bar"
end
puts var_name
>> "bar"
場合によってはコードをコンパクトにするのに役立ちます。
あなたの環境では正規表現はサポートされていませんか?例えば。 Shopify スクリプトエディタ (2018年4月):
[エラー]:未初期化定数 RegExp
here および here で既に説明した方法の組み合わせによる回避策。
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
||
は.include?
よりも優先順位が高いので、クラスメソッドステートメントでor
sを使用しました。あなたが Ruby-nazi であるなら、私が代わりにこの(item.include? 'A') || ...
を使ったと想像してください。 repl.it test。
When句でカンマ「、」を強調することは重要です。|| if文の場合、つまり、when句の区切られた式の間ではAND比較ではなく、OR比較を行います。以下のcase文をチェックしてください。明らかに、xは2以上ですが、戻り値は 'Apple'です。どうして? xは3であり、 '、'は||として機能するので、式 'x <2'を評価するのに面倒ではありませんでした。
x = 3
case x
when 3, x < 2 then 'Apple'
when 3, x > 2 then 'orange'
end
=> "Apple"
あなたは、ANDを実行するために、以下のようなことができると思うかもしれません。しかし、うまくいきません。これは、(3 && x> 2)がtrueと評価され、RubyがTrueの値を取り、それを===でxと比較するためです。xは3なので、これは明らかに正しくありません。
case x
when (3 && x < 2) then 'Apple'
when (3 && x > 2) then 'orange'
end
=> nil
&&比較を行うには、case likeを扱い、if elseでブロックする必要があります。
case
when x == 3 && x < 2 then 'Apple'
when x == 3 && x > 2 then 'orange'
end
Rubyプログラミング言語の本の中で、Matzはこの後者の形式は単純な(そしてまれにしか使われない)形式であると言っています。これはif/elsif/elseの代替構文にすぎません。しかし、使用頻度が低いかどうかにかかわらず、特定の 'when'句に複数の&&式を付加する他の方法はありません。