switch
Ruby'de nasıl ifade yazabilirim ?
switch
Ruby'de nasıl ifade yazabilirim ?
Yanıtlar:
Ruby bunun yerine case
ifadeyi kullanır.
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
yan tümcedeki nesneyi işleç case
kullanarak yan tümcedeki nesneyle karşılaştırır ===
. Örneğin, 1..5 === x
değil x === 1..5
.
Bu, when
yukarıda görüldüğü gibi sofistike hükümlere izin verir . Sıradağlar, sınıflar ve her türlü şey eşitlikten ziyade test edilebilir.
Aksine switch
diğer birçok dilde ifadeleri, Ruby'nin case
yok sonbahar-through böylece her bitirmek için gerek yoktur, when
bir ile break
. Ayrıca, tek bir when
cümlede birden çok eşleşme belirtebilirsiniz when "foo", "bar"
.
when
ve return
satırını aynı satıra koyarak kodunuzu kısaltabilirsiniz :when "foo" then "bar"
then
. Lütfen diğer cevaplara da bakınız.
case...when
sınıfları işlerken beklenmedik bir şekilde davranır. Bunun nedeni ===
operatörü kullanmasıdır.
Bu operatör değişmez değerlerle beklendiği gibi çalışır, ancak sınıflarla çalışmaz:
1 === 1 # => true
Fixnum === Fixnum # => false
Bu, case ... when
bir nesnenin sınıfının üzerinde yapmak istiyorsanız , bunun işe yaramayacağı anlamına gelir:
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
"Bir dize veya sayı değil" yazdıracak.
Neyse ki, bu kolayca çözülebilir. ===
Döndürecek şekilde operatör tanımlanmıştır true
bir sınıf ile kullanmak ve ikinci işlenen olarak bu sınıfın bir örneğini temin edin:
Fixnum === 1 # => true
Kısacası, yukarıdaki kod aşağıdakileri kaldırarak düzeltilebilir .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
Bugün bu soruyu bir cevap ararken vurdum ve bu ilk görünen sayfaydı, bu yüzden aynı durumdaki başkaları için yararlı olacağını düşündüm.
.class
almak not etmek ilginç, teşekkürler. Tabii ki, bu tamamen uygun bir davranış (gerçi bunun yazdırmayı düşünmenin yaygın bir hata olabileceğini görebiliyordum It is a string
) ... nesnenin kendisini değil, keyfi bir nesnenin sınıfını test ediyorsunuz . Yani, örneğin: case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end
sonuçlardan: "Class!"
Bu aynı şekilde çalışır 1.class
, {}.class
vb bırakarak .class
, biz olsun "String!"
veya "Something else"
bu çeşitli değerler için.
case
Ruby'de kullanılarak yapılır . Ayrıca Wikipedia'da " Geçiş ifadesi " konusuna bakın .
Alıntı:
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
Başka bir örnek:
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'daki Ruby Programlama Dili'nin (1. Baskı, O'Reilly) yaklaşık 123. sayfasında then
, when
cümleleri takip eden anahtar kelimenin bir satırsonu veya noktalı virgülle ( if then else
sözdiziminde olduğu gibi ) değiştirilebileceği belirtiliyor. (Ruby 1.8 de yerine iki nokta üst üste işaretine izin verir then
, ancak bu sözdizimine artık Ruby 1.9'da izin verilmez.)
when (-1.0/0.0)..-1 then "Epic fail"
type = #{score}
Her satırı söylemek yerine , yaptığınızı kopyalayabilirim. Çok daha zarif Ben de tek gömlekleri daha iyi seviyorum (mümkünse)
Chuck'ın cevabına daha fazla örnek eklemek için :
Parametre ile:
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
Parametre olmadan:
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
Lütfen, kikito'nun uyardığı " Ruby'de bir anahtar deyimi nasıl yazılır? "
or
Birçok programlama dili, özellikle de C'den türetilmiş olanlar, Geçiş Anahtarı için destek sağlar . Ruby'de aynı şeyi yapmanın en iyi yolunu arıyordum ve başkaları için yararlı olabileceğini düşündüm:
C-benzeri dillerde, geçiş tipik olarak şöyle görünür:
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'de aynı şey şu şekilde elde edilebilir:
case expression
when 'a', 'b', 'c'
# Do something for a, b or c
when 'd', 'e'
# Do something else for d or e
end
Bu kesinlikle eşdeğer değildir, çünkü veya 'ya 'a'
düşmeden önce bir kod bloğu yürütmek mümkün değildir , ancak çoğunlukla aynı şekilde yararlı olacak kadar benzer buluyorum.'b'
'c'
Ruby 2.0'da lambdas'ı case
aşağıdaki gibi ifadelerde de kullanabilirsiniz :
is_even = ->(x) { x % 2 == 0 }
case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end
Özel bir Yapı kullanarak kendi karşılaştırıcılarınızı da kolayca oluşturabilirsiniz ===
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
(" Proclar Ruby 2.0'daki vaka ifadeleriyle kullanılabilir mi? "
Veya tam bir sınıfla:
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
(" Bir Ruby Case İfadesi Nasıl Çalışır ve Bununla Ne Yapabilirsiniz " örneğinden alınmıştır .)
Bir dize türü bulma gibi normal ifadeler kullanabilirsiniz:
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
bunun için eşitlik işleneni kullanacak ===
(teşekkürler @JimDeville). Daha fazla bilgi " Ruby Operatörleri " nde bulunabilir . Bu, @mmdemirbas örneği (parametre olmadan) kullanılarak da yapılabilir, sadece bu yaklaşım bu tür durumlar için daha temizdir.
Ruby anahtar durumunda OR koşulunun nasıl kullanılacağını bilmek istiyorsanız:
Yani, bir de case
açıklamada, bir ,
eşdeğerdir ||
bir in if
ifadesi.
case car
when 'Maruti', 'Hyundai'
# Code here
end
Bkz. " Ruby Case İfadesi Nasıl Çalışır ve Bununla Neler Yapabilirsiniz ".
Denir case
ve beklediğiniz gibi çalışır, ayrıca ===
testleri uygulayan çok daha eğlenceli şeyler .
case 5
when 5
puts 'yes'
else
puts 'else'
end
Şimdi biraz eğlenmek için:
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
Ve ortaya çıkıyorsa, / else zincirini (yani, testler ortak bir değişkeni içermese bile) case
, ilk case
parametreyi bırakarak ve sadece ilk eşleşmenin istediğiniz şey olduğu ifadeleri yazarak değiştirebilirsiniz.
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 deyimlerini yazmak için kullanır .
Gereğince case
belgeler:
Vaka ifadeleri, bir argüman konumunda olan isteğe bağlı bir koşul
case
ve sıfır veya daha fazlawhen
cümleden oluşur.when
Koşulla eşleşen ilk koşul (veya koşul boşsa Boole gerçeğini değerlendirmek için) “kazanır” ve kod stanzaları yürütülür. Vaka ifadesinin değeri, başarılıwhen
maddenin veyanil
böyle bir maddenin bulunmadığı değerdir .Vaka ifadesi bir
else
cümle ile sona erebilir . Herwhen
ifadenin virgülle ayrılmış birden fazla aday değeri olabilir.
Misal:
case x
when 1,2,3
puts "1, 2, or 3"
when 10
puts "10"
else
puts "Some other number"
end
Kısa versiyon:
case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end
Ve " Ruby'nin durum bildirimi - ileri teknikler " olarak Ruby case
;
Aralıklarla kullanılabilir :
case 5
when (1..10)
puts "case statements match inclusion in a range"
end
## => "case statements match inclusion in a range"
Regex ile kullanılabilir :
case "FOOBAR"
when /BAR$/
puts "they can match regular expressions!"
end
## => "they can match regular expressions!"
Procs ve Lambdas ile kullanılabilir :
case 40
when -> (n) { n.to_s == "40" }
puts "lambdas!"
end
## => "lambdas"
Ayrıca, kendi maç sınıflarınızla birlikte kullanılabilir:
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
Durumunuza bağlı olarak, bir karma yöntem kullanmayı tercih edebilirsiniz.
Uzun bir when
s listesi varsa ve her birinin karşılaştırılacak bir somut değeri varsa (bir aralık değil), bir yöntem karma değeri bildirmek ve daha sonra ilgili yöntemi karmadan böyle çağırmak daha etkili olacaktır.
# 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])
Yana switch case
her zaman tek nesnesi döndüren, biz Sonuçlarını doğrudan yazdırabilirsiniz:
puts case a
when 0
"It's zero"
when 1
"It's one"
end
Çok değerli zaman ve değersiz durum:
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
Ve burada düzenli bir ifade çözümü:
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
(burada ,
satırsonu anlamına gelir)
case
Ruby'de iki farklı şekilde ifade yazabilirsiniz :
if
ifadeye benzercase
ve her bir when
madde hedefle karşılaştırılır.age = 20
case
when age >= 21
puts "display something"
when 1 == 0
puts "omg"
else
puts "default condition"
end
veya:
case params[:unknown]
when /Something/ then 'Nothing'
when /Something else/ then 'I dont know'
end
Çok büyük cevaplar ama bir factoid ekleyeceğini düşündüm .. Nesneleri karşılaştırmaya çalışıyorsanız (Sınıflar) bir uzay gemisi yöntemi (şaka değil) olduğundan emin olun veya nasıl karşılaştırıldığını anlayın
“ Ruby Eşitliği ve Nesne Karşılaştırması ” konuyla ilgili güzel bir tartışma.
<=>
karşılaştırmanın sırasıyla daha küçük, eşit, daha büyük veya karşılaştırılamaz olarak dönmesine bağlı olarak -1, 0, 1 veya nil döndürmek için kullanılan "uzay gemisi" yöntemi kullanılır. Ruby'nin Karşılaştırılabilir modül belgeleri bunu açıklıyor.
Yukarıdaki cevapların çoğunda belirtildiği gibi, ===
operatör case
/ when
ifadeleri altında kullanılır .
İşte bu operatör hakkında ek bilgi:
===
Ruby'nin String, Range ve Regexp gibi yerleşik sınıflarının birçoğu ===
"case-equality", "triple equals" veya "threequals" olarak da bilinen operatörün kendi uygulamalarını sağlar . Her sınıfta farklı uygulandığından, çağrıldığı nesnenin türüne bağlı olarak farklı davranacaktır. Genel olarak, sağdaki "sol" nesnesinin "veya" nesnesinin "üyesi" ise doğru değerini döndürür. Örneğin, bir nesnenin bir sınıfın (ya da alt sınıflarından birinin) bir örneği olup olmadığını test etmek için kullanılabilir.
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
Aynı sonuç, muhtemelen iş için en uygun olan diğer yöntemlerle is_a?
ve gibi elde edilebilir instance_of?
.
===
Ne zaman ===
operatör bir dizi nesne üzerinde çağrılır sağda değer soldaki aralığa giriyorsa, bu doğru döner.
(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
===
Operatörün ===
sol nesnenin yöntemini çağırdığını unutmayın . Yani buna (1..4) === 3
eşdeğerdir (1..4).=== 3
. Başka bir deyişle, sol taraftaki işlenenin sınıfı, ===
yöntemin hangi uygulamasına çağrılacağını tanımlayacaktır , bu nedenle işlenen konumları birbirinin yerine kullanılamaz.
===
Sağdaki dize, soldaki normal ifadeyle eşleşiyorsa true değerini döndürür.
/zen/ === "practice zazen today" # Output: => true
# is similar to
"practice zazen today"=~ /zen/
Yukarıdaki iki örnek arasındaki tek fark, bir eşleşme olduğunda ===
true =~
değerini ve Ruby'de doğru bir değer olan bir tamsayıyı döndürmesidir. Yakında buna geri döneceğiz.
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
Daha fazla bilgi için bkz. " Ruby - if ... else, case, sürece ".
Kullanmaya başladım:
a = "secondcase"
var_name = case a
when "firstcase" then "foo"
when "secondcase" then "bar"
end
puts var_name
>> "bar"
Bazı durumlarda kompakt koda yardımcı olur.
Hash
bir case
ifade yerine a kullanılarak yapılmalıdır .
Ortamınızdaki düzenli ifadeler için destek yok mu? Örneğin Shopify Script Editor (Nisan 2018):
[Hata]: başlatılmamış sabit RegExp
Daha önce burada ve burada ele alınan yöntemlerin bir kombinasyonunu izleyen bir geçici çözüm :
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ınıf yöntemi deyiminde s kullandığımdan ||
daha yüksek önceliğe sahip
.include?
. Eğer bir yakut-nazi iseniz , lütfen (item.include? 'A') || ...
bunun yerine kullandığımı hayal edin . repl.it testi.
Bir cümledeki virgül ( ,
) öğesini vurgulamak önemlidir when
. ||
Bir if
deyim olarak hareket eder , yani, cümlenin sınırlandırılmış ifadeleri arasında VE karşılaştırması değil, OR karşılaştırması yapar . Aşağıdaki vaka bildirimlerine bakın:when
x = 3
case x
when 3, x < 2 then 'apple'
when 3, x > 2 then 'orange'
end
=> "apple"
x
2'den az değil, ancak dönüş değeri "apple"
. Neden? Çünkü 3'dü x
ve ',`` acts as an
|| , it did not bother to evaluate the expression
x <2 '.
Bir VE yapmak için aşağıdaki gibi bir şey yapabileceğinizi düşünebilirsiniz , ancak işe yaramaz:
case x
when (3 && x < 2) then 'apple'
when (3 && x > 2) then 'orange'
end
=> nil
Çünkü çalışmıyor (3 && x > 2)
true değerlendirir ve Ruby Gerçek değerini alır ve karşılaştırır x
ile ===
beri, doğru değil, x
3'tür.
Bir &&
karşılaştırma yapmak için / block case
gibi davranmanız gerekir :if
else
case
when x == 3 && x < 2 then 'apple'
when x == 3 && x > 2 then 'orange'
end
Ruby Programlama Dili kitabında Matz, bu son formun basit (ve nadiren kullanılan) form olduğunu ve bunun if
/ elsif
/ için alternatif bir sözdiziminden başka bir şey olmadığını söylüyor else
. Ancak, nadiren kullanılsın veya kullanılmasın, &&
belirli bir when
fıkra için birden fazla ifade eklemenin başka bir yolunu görmüyorum .
if...elsif
? Bir vaka bildirimi ile bir koşulu karıştırmaya çalıştığınız anlaşılıyor. Neden? Koşullu zaman bloğunun içine koyun , örn. when 3; ( x < 2 ) ? 'apple' : 'orange'
Birden fazla koşul için switch deyimi yazabiliriz.
Örneğin,
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
) Harf duyarlıdır ve bunun gibi büyük olamaz.
NoMethodError (undefined method
CASE 'için main: Object) `. @ Sondra.kinsey'in söylediği gibi, büyük harf kullanamazsınız. Ruby bunun bir SABİT olduğunu düşünecek.
case
İfadesi operatörü gibidir switch
diğer dillerde.
Bu switch...case
C'deki sözdizimidir :
switch (expression)
{
case constant1:
// statements
break;
case constant2:
// statements
break;
.
.
.
default:
// default statements
}
Bu case...when
Ruby'nin sözdizimi :
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
Örneğin:
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
Daha fazla bilgi için case
belgelere bakın .