Jak napisać instrukcję switch w Ruby?
Jak napisać instrukcję switch w Ruby?
21 answers
Ruby używa case
wyrażenie zamiast.
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 porównuje obiekt w klauzuli when
z obiektem w klauzuli case
używając operatora ===
. Na przykład 1..5 === x
, a nie x === 1..5
.
Pozwala to na wyrafinowane when
klauzule, jak pokazano powyżej. Zakresy, klasy i wszelkiego rodzaju rzeczy mogą być testowane zamiast tylko równości.
W przeciwieństwie do switch
w wielu innych językach, case
Ruby nie posiada , więc nie ma potrzeby kończenia każdego {[2] } znakiem break
. Możesz również określić wiele dopasowań w pojedynczej klauzuli when
, takiej jak when "foo", "bar"
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 09:03:49
case...when
zachowuje się nieco nieoczekiwanie podczas obsługi klas. Wynika to z faktu, że używa operatora ===
.
Ten operator działa zgodnie z oczekiwaniami z literałami, ale nie z klasami:
1 === 1 # => true
Fixnum === Fixnum # => false
Oznacza to, że jeśli chcesz wykonać case ... when
nad klasą obiektu, to nie zadział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')
end
Wydrukuje "to nie jest łańcuch".
Na szczęście jest to łatwe do rozwiązania. Operator ===
został zdefiniowany tak, że zwraca true
, jeśli użyjesz go z klasą i podaj instancję tej klasy jako drugi operand:
Fixnum === 1 # => true
W skrócie, powyższy kod można naprawić, usuwając .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
Trafiłem dziś w ten problem, szukając odpowiedzi, i to była pierwsza pojawiająca się strona, więc pomyślałem, że przyda się innym w tej samej sytuacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-11 19:04:00
Robi się to przez case w Ruby. Zobacz też Ten artykuł na Wikipedii.
Cytat:
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
Inny przykład:
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
Na stronie 123 (używam Kindle) w Ruby Lanugage (1st Edition, O ' Reilly), jest napisane, że słowo kluczowe then
po klauzulach when
można zastąpić znakiem nowej linii lub średnikiem (tak jak w składni if then else
). (Ruby 1.8 pozwala również na dwukropek zamiast then
... Ale składnia ta nie jest już dozwolona w Ruby 1.9.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 02:40:33
Sprawa...kiedy
Aby dodać więcej przykładów do odpowiedź Chucka :
Z parametrem:
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
Bez parametru:
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
Proszę, bądźcie świadomiproblemu , który ostrzega kikito.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:34
Wiele języków programowania, zwłaszcza tych wywodzących się z C, posiada wsparcie dla tak zwanegoSwitch Fallthrough . Szukałam najlepszego sposobu, aby zrobić to samo w Ruby i pomyślałam, że może się to przydać innym: {]}
W językach C-podobnych fallthrough zazwyczaj wygląda tak:
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;
}
W Rubim to samo można osiągnąć w następujący sposób:
case expression
when 'a', 'b', 'c'
# Do something for a, b or c
when 'd', 'e'
# Do something else for d or e
end
Nie jest to ściśle równoważne, ponieważ nie jest możliwe, aby 'a'
wykonać blok kodu przed spadając do 'b'
lub 'c'
, ale w większości uważam, że jest wystarczająco podobny, aby być użytecznym w ten sam sposób.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-06 01:59:39
W Rubim 2.0, Możesz również używać lambda w case
instrukcjach, w następujący sposób:
is_even = ->(x) { x % 2 == 0 }
case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end
Możesz również łatwo tworzyć własne komparatory za pomocą struktury z niestandardowym ===
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
(przykład zaczerpnięty z "czy procs może być używany z instrukcjami case w Ruby 2.0?".)
Lub, z pełną klasą:
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
(przykład zaczerpnięty z " Jak działa Instrukcja Case Ruby i co możesz z nią zrobić".)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:11
Możesz używać wyrażeń regularnych, takich jak znajdowanie typu ciągu znaków:
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 ' s case
użyje do tego operand równości ===
(dzięki @ JimDeville). Dodatkowe informacje są dostępne na stronie "operatory Ruby ". Można to również zrobić za pomocą przykładu @mmdemirbas (bez parametru), tylko takie podejście jest czystsze dla tego typu przypadków.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-17 03:47:49
Jeśli chcesz wiedzieć, jak użyć warunku OR w przypadku przełącznika Ruby:
Tak więc, w case
twierdzenie, ,
jest odpowiednikiem ||
w if
twierdzenie.
case car
when 'Maruti', 'Hyundai'
# Code here
end
Wiele innych rzeczy, które możesz zrobić za pomocą instrukcji case Ruby
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 02:46:05
Nazywa się case
i działa tak, jak można się spodziewać, plus dużo więcej zabawnych rzeczy dzięki uprzejmości ===
, która wdraża testy.
case 5
when 5
puts 'yes'
else
puts 'else'
end
Teraz dla Zabawy:
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
I okazuje się, że możesz również zastąpić dowolny łańcuch if / else (to znaczy, nawet jeśli testy nie zawierają wspólnej zmiennej) case
, pomijając początkowy parametr case
i pisząc wyrażenia, w których pierwsze dopasowanie jest tym, czego chcesz.
case
when x.nil?
...
when (x.match /'^fn'/)
...
when (x.include? 'substring')
...
when x.gsub('o', 'z') == 'fnzrq'
...
when Time.now.tuesday?
...
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-30 22:48:00
W zależności od przypadku, możesz użyć hash metod.
Jeśli istnieje długa lista kiedy i każdy z nich ma konkretną wartość do porównania (nie interwał), bardziej efektywne będzie zadeklarowanie hasha metod, a następnie wywołanie odpowiedniej metody z tego hasha w ten sposób.
# 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])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 02:47:41
Ponieważ switch case
zawsze Zwraca pojedynczy obiekt, możemy bezpośrednio wydrukować jego wynik:
puts case a
when 0
"It's zero"
when 1
"It's one"
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 02:42:17
Wielowartościowe when i bez wartości case:
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
I Wyrażenie regularne rozwiązanie tutaj:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 02:45:03
Ruby używa case
do pisania instrukcji switch.
Zgodnie z Ruby Docs :
Deklaracje przypadków składają się z warunku opcjonalnego, który jest w pozycja argumentu
case
i zero lub więcejwhen
klauzul. Pierwszawhen
klauzula dopasowująca warunek (lub oceniająca do Boolean truth, jeśli warunek jest null)" wins", a jego strofa kodu jest wykonywany. Wartością instrukcji case jest wartość successfulwhen
klauzula, lubnil
jeśli nie ma takiej klauzuli.Deklaracja przypadku może zakończyć się klauzulą
else
. Każdywhen
a instrukcja może mieć wiele wartości kandydujących, oddzielonych przecinkami.
Przykład:
case x
when 1,2,3
puts "1, 2, or 3"
when 10
puts "10"
else
puts "Some other number"
end
Wersja skrócona:
case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end
I jak ten blog by Honeybadger opisuje przypadek Ruby;
Może być używany z zakresami :
case 5
when (1..10)
puts "case statements match inclusion in a range"
end
## => "case statements match inclusion in a range"
Może być używany z Regex :
case "FOOBAR"
when /BAR$/
puts "they can match regular expressions!"
end
## => "they can match regular expressions!"
Może być używany z Procs i Lambda:
case 40
when -> (n) { n.to_s == "40" }
puts "lambdas!"
end
## => "lambdas"
Może być również używany z własnymi klasami meczowymi:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-22 09:27:32
W Rubim możesz pisać wyrażenia case na dwa różne sposoby.
- podobne do szeregu twierdzeń" if "
- określ cel obok przypadku i każda klauzula" kiedy " jest porównywana z celem.
Pierwsza droga
age = 20
case
when age >= 21
puts "display something"
when 1 == 0
puts "omg"
else
puts "default condition"
end
Druga droga
case params[:unknown]
when /Something/ then 'Nothing'
when /Something else/ then 'I dont know'
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-16 17:45:44
Wiele świetnych odpowiedzi, ale pomyślałem, że dodam jeden fakt.. Jeśli próbujesz porównać obiekty (klasy), upewnij się, że masz metodę statku kosmicznego (nie żart) lub zrozumieć, w jaki sposób są one porównywane
Oto dobra dyskusja na ten temat http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-06 20:18:37
Możesz to zrobić w bardziej naturalny sposób,]}
case expression
when condtion1
function
when condition2
function
else
function
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-26 09:15:12
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-12 06:33:17
Jak stwierdzono w wielu z powyższych odpowiedzi, operator === jest używany pod maską w poleceniach case / when.
Oto kilka dodatkowych informacji o tym operatorze.
Operator równości przypadków: = = =
Wiele wbudowanych klas Rubiego, takich jak String, Range i Regexp, dostarcza własnych implementacji operatora===, znanego również jako case-equality, triple equals lub threequals. Ponieważ jest zaimplementowany inaczej w każdej klasie, będzie zachowywał się inaczej w zależności na temat rodzaju obiektu, na który został wywołany. Zazwyczaj zwraca true, jeśli obiekt po prawej stronie "należy do "lub" jest członkiem " obiektu po lewej stronie. Na przykład, może być użyty do sprawdzenia, czy obiekt jest instancją klasy (lub jednej z jej podklas).
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
Ten sam wynik można osiągnąć za pomocą innych metod, które prawdopodobnie najlepiej nadają się do tego zadania, takich jak is_a? a instance_of?.
Implementacja zakresu = = =
Gdy operator = = = jest wywoływany na przedziale obiekt, zwraca true, jeśli wartość po prawej mieści się w zakresie po lewej stronie.
(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
Pamiętaj, że operator = = = wywołuje metodę = = = obiektu lewej ręki. So (1..4) = = = 3 jest równoważne (1..4).=== 3. Innymi słowy, Klasa operandu lewej strony określi, która implementacja metody === zostanie wywołana, więc pozycje operandu nie są wymienne.
Implementacja Regexp = = =
Zwraca true, jeśli łańcuch po prawej stronie pasuje do wyrażenia regularnego po lewej stronie. / zen / = = = "praktyka zazen dzisiaj" # wyjście: => true # jest podobny do "praktyka zazen dzisiaj" = ~/zen /
Jedyną istotną różnicą między dwoma powyższymi przykładami jest to, że gdy istnieje dopasowanie, = = = zwraca true i = ~ zwraca liczbę całkowitą, która jest prawdziwą wartością w Rubim. Wrócimy do tego wkrótce.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-06 16:07:17
$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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-13 09:28:06
Zacząłem używać:
a = "secondcase"
var_name = case a
when "firstcase" then "foo"
when "secondcase" then "bar"
end
puts var_name
>> "bar"
Pomaga skompaktować kod w niektórych przypadkach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 02:46:39
Brak wsparcia dla wyrażeń regularnych w Twoim środowisku? E. g. Shopify Edytor skryptów (kwiecień, 2018):
[Error]: stała nieznitializowana RegExp
Obejście po kombinacji metod już wcześniej omówionych w tutaj i tutaj :
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
Użyłem or
s w instrukcji metody klasy, ponieważ ||
ma wyższy priorytet niż
.include?
. Jeśli jesteś ruby-nazi, proszę. wyobraź sobie, że zamiast tego użyłem tego (item.include? 'A') || ...
. repl.it test.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-18 11:29:29