2217

switchRubyでステートメントを書くにはどうすればよいですか?

4

27 に答える 27

2859

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 === xx === 1..5

これにより、上記のように洗練されたwhen句が可能になります。範囲、クラス、およびあらゆる種類のものは、単なる平等ではなくテストできます。

switch他の多くの言語のステートメントとは異なり、Rubycaseにはフォールスルーwhenがないため、それぞれをで終了する必要はありませんbreakwhenのように、1つの句で複数の一致を指定することもできますwhen "foo", "bar"

于 2009-06-04T01:22:57.180 に答える
475

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 or number')
end

「文字列または数値ではありません」と出力されます。

幸い、これは簡単に解決できます。演算子は、クラスで使用し、そのクラスのインスタンスを2番目のオペランドとして===指定すると返されるように定義されています。true

Fixnum === 1 # => true

要するに、上記のコードは.classfromを削除することで修正できますcase obj.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

今日、答えを探しているときにこの問題にぶつかりました。これが最初に表示されたページだったので、同じ状況で他の人にも役立つと思いました。

于 2011-04-17T15:20:14.847 に答える
237

これはcaseRubyで使用して行われます。ウィキペディアの「 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では使用できなくなりました。)

于 2009-06-04T01:20:35.813 に答える
113

ケース...いつ

チャックの答えにさらに例を追加するには:

パラメータ付き:

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ステートメントを書く方法」に注意してください。

于 2012-07-05T13:19:42.310 に答える
81

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

(「Ruby2.0のcaseステートメントでprocsを使用できますか?」から抜粋した例。)

または、完全なクラスの場合:

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ステートメントのしくみとそれを使って何ができるか」から抜粋した例。)

于 2013-08-01T00:04:53.747 に答える
80

多くのプログラミング言語、特にCから派生した言語は、いわゆるSwitchFallthroughをサポートしています。私は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'

于 2013-12-07T12:11:35.870 に答える
53

文字列のタイプを検索するなど、正規表現を使用できます。

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に感謝)。追加情報は「RubyOperators」で入手できます。これは、@ mmdemirbasの例(パラメーターなし)を使用して実行することもできます。これらのタイプのケースでは、このアプローチのみがよりクリーンです。

于 2012-10-16T12:17:41.390 に答える
37

それは呼ばれ、あなたが期待するように機能します。さらに、テストを実装するための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また、初期caseパラメーターを省略し、最初の一致が必要な場所に式を記述するだけで、任意のif / elseチェーン(つまり、テストに共通変数が含まれていない場合でも)を置き換えることもできます。

case
  when x.nil?
    ...
  when (x.match /'^fn'/)
    ...
  when (x.include? 'substring')
    ...
  when x.gsub('o', 'z') == 'fnzrq'
    ...
  when Time.now.tuesday?
    ...
end
于 2016-02-05T20:40:16.493 に答える
33

Rubyスイッチの場合にOR条件を使用する方法を知りたがっている場合:

したがって、caseステートメントでは、aはステートメント内,と同等です。||if

case car
   when 'Maruti', 'Hyundai'
      # Code here
end

RubyCaseステートメントのしくみとそれを使って何ができるか」を参照してください

于 2014-07-03T06:46:12.123 に答える
25

Rubyは、caseswitchステートメントの記述にforを使用します。

ドキュメントによるとcase

Caseステートメントは、引数の位置にあるオプションの条件とcase、0個以上のwhen句で構成されます。when条件に一致する(または条件がnullの場合はブール値の真理に評価される)最初の句が「勝ち」、そのコードスタンザが実行されます。caseステートメントの値は、success句の値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のcaseステートメント-高度なテクニック」が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
于 2016-07-18T19:59:10.573 に答える
22

場合によっては、メソッドのハッシュを使用することをお勧めします。

sの長いリストがあり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])
于 2014-09-18T14:48:15.287 に答える
21

switch case常に単一のオブジェクトを返すため、その結果を直接出力できます。

puts case a
     when 0
        "It's zero"
     when 1
        "It's one"
     end
于 2013-11-05T07:29:51.127 に答える
20

複数値の場合と値のない場合:

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
于 2014-01-20T11:45:28.337 に答える
14

caseRubyでは2つの異なる方法で式を書くことができます。

  1. 一連のifステートメントに似ています
  2. の横にターゲットを指定する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
于 2017-02-16T09:32:15.767 に答える
11

あなたはもっと自然な方法でこのようにすることができます、

case expression
when condtion1
   function
when condition2
   function
else
   function
end
于 2016-05-26T09:15:12.577 に答える
9

すばらしい答えがたくさんありますが、ファクトイドを1つ追加すると思いました。オブジェクト(クラス)を比較する場合は、宇宙船メソッド(ジョークではない)があることを確認するか、それらがどのように比較されているかを理解してください。

Rubyの同等性とオブジェクトの比較」は、このトピックに関する優れた議論です。

于 2013-08-06T20:18:37.090 に答える
8

上記の回答の多くで述べられているように、===演算子はcase/whenステートメントの内部で使用されます。

その演算子に関する追加情報は次のとおりです。

大文字小文字の等式演算子:===

===String、Range、RegexpなどのRubyの組み込みクラスの多くは、「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?

の範囲実装===

演算子が範囲オブジェクトで呼び出された場合===、右側の値が左側の範囲内にある場合は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/ === "practice zazen today"  # Output: => true
# is similar to
"practice zazen today"=~ /zen/

上記の2つの例の唯一の関連する違いは、一致する場合、===trueを=~返し、整数を返すことです。これは、Rubyの真の値です。すぐにこれに戻ります。

于 2016-07-06T16:07:17.373 に答える
5
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
于 2016-03-12T06:33:17.583 に答える
4

私は使い始めました:

a = "secondcase"

var_name = case a
  when "firstcase" then "foo"
  when "secondcase" then "bar"
end

puts var_name
>> "bar"

場合によってはコードをコンパクトにするのに役立ちます。

于 2014-07-07T21:18:24.903 に答える
4
$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、unless」を参照してください。

于 2017-11-13T07:58:42.167 に答える
3

ご使用の環境で正規表現はサポートされていませんか?例: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を使用しました。||.include?

それでも使用したい||場合は、この場合orは望ましいですが、代わりにこれを行うことができます(item.include? 'A') || ...。このrepl.itでテストできます。

于 2018-04-18T11:29:29.163 に答える
3

句内のコンマ(,)を強調することが重要です。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"です。なんで?x3歳から',`` acts as an|| , it did not bother to evaluate the expressionx<2'。

ANDを実行すると、以下のようなことができると思うかもしれませんが、機能しません。

case x
  when (3 && x < 2) then 'apple'
  when (3 && x > 2) then 'orange'
end
 => nil 

(3 && x > 2)がtrueと評価され、RubyがTrue値を取得し、それをと比較するためx、機能しません。これは、が3===であるため、trueではありませんx

&&比較するには、/ブロックのように扱う必要がありますcaseifelse

case
  when x == 3 && x < 2 then 'apple'
  when x == 3 && x > 2 then 'orange'
end

Rubyプログラミング言語の本の中で、Matzは、この後者の形式は単純な(そしてあまり使用されない)形式であり、//の代替構文にすぎないと述べてifelsifますelse。ただし、使用頻度が低いかどうかに関係なく、特定の句に複数の&&式を付加する方法は他にありません。when

于 2019-03-20T20:16:13.740 に答える
3

「より小さい」または「より大きい」が必要な場合:

case x
when 1..5
  "It's between 1 and 5"
when 6
  "It's 6"
when 7..1.0/0
  "It's equal or greater than 7"
when -1.0/0..0
  "It's equal or less than 0"
end

1.0/0はに等しいFloat::INFINITYので、好きなものを使用できます。

Ruby 2.6以降は、 Endless Rangesを使用できます。Ruby2.7以降では、 Beginless Rangesも使用できるため、次のように実行できます。

case x
when 1..5
  "It's between 1 and 5"
when 6
  "It's 6"
when (7..)
  "It's equal or greater than 7"
when (..0)
  "It's equal or less than 0"
end
于 2021-04-29T09:25:02.983 に答える
2

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ドキュメントを参照してください。

于 2019-11-01T13:35:22.473 に答える
1

複数の条件に対して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
于 2019-01-25T07:32:41.587 に答える
1

Rubyは代わりにcase式をサポートしています。

クラスマッチング:

case e = StandardError.new("testing")
when Exception then puts "error!"
else puts "ok!"
end # => error! 

複数値のマッチング:

case 3
when 1,2,3 then puts "1..3"
when 4,5,6 then puts "4..6"
else puts "?"
end # => 1..3

正規表現の評価:

case "monkey"
when /mon/ then puts "banana"
else puts "?" 
end # => banana
于 2021-07-22T23:42:52.067 に答える
0

ユースケース+よりも

number = 10

case number
when 1...8 then # ...
when 8...15 then # ...
when 15.. then # ...
end
于 2021-02-17T19:00:03.047 に答える