Câu hỏi Làm thế nào để viết một tuyên bố chuyển đổi trong Ruby?


Làm thế nào để viết một câu lệnh switch trong Ruby?


1833
2018-06-04 01:18


gốc




Các câu trả lời:


Ruby sử dụng case biểu hiện thay thế.

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 so sánh đối tượng trong when mệnh đề với đối tượng trong case khoản sử dụng === nhà điều hành. Ví dụ, 1..5 === x, và không x === 1..5.

Điều này cho phép tinh vi when các mệnh đề như đã thấy ở trên. Phạm vi, các lớp học và tất cả mọi thứ có thể được kiểm tra thay vì chỉ là bình đẳng.

không giống switch báo cáo bằng nhiều ngôn ngữ khác, Ruby case không có mùa thu, vì vậy không cần phải kết thúc mỗi when với một break. Bạn cũng có thể chỉ định nhiều kết quả phù hợp trong một when mệnh đề như when "foo", "bar".


2306
2018-06-04 01:22



railsless.blogspot.com/2011/01/… - Pankaj
Bạn cũng có thể thực hiện regex trên đối số đã truyền: khi / thisisregex / hàng tiếp theo  đặt "Đây là kết quả được tìm thấy nr. 1 # {$ 1}" kết thúc - Automatico
Cũng đáng chú ý, bạn có thể rút ngắn mã của mình bằng cách đặt when và return tuyên bố trên cùng một dòng: when "foo" then "bar" - Alexander


case...when cư xử một chút bất ngờ khi xử lý các lớp. Điều này là do thực tế là nó sử dụng === nhà điều hành.

Toán tử đó hoạt động như mong đợi với các chữ, nhưng không hoạt động với các lớp:

1 === 1           # => true
Fixnum === Fixnum # => false

Điều này có nghĩa là nếu bạn muốn làm case ... when trên lớp của đối tượng, điều này sẽ không hoạt động:

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

Sẽ in "Nó không phải là một chuỗi".

May mắn thay, điều này dễ dàng được giải quyết. Các === toán tử đã được xác định để nó trả về true nếu bạn sử dụng nó với một lớp và cung cấp một cá thể của lớp đó làm toán hạng thứ hai:

Fixnum === 1 # => true

Tóm lại, đoạn mã trên có thể được sửa bằng cách xóa .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

Tôi đã gặp vấn đề này ngày hôm nay trong khi đang tìm kiếm câu trả lời, và đây là trang xuất hiện đầu tiên, vì vậy tôi thấy nó sẽ hữu ích cho những người khác trong cùng một tình huống của tôi.


397
2018-04-17 15:20



obj = 'hello'; trường hợp obj; khi 'hello' sau đó đặt "It's hello" end - v Sugumar


Nó được thực hiện bởi trường hợp trong Ruby. Cũng thấy bài viết này trên Wikipedia.

Trích dẫn:

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

Một vi dụ khac:

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

Trên trang 123 (Tôi đang sử dụng Kindle) Lập trình Ruby Lanugage (1st Edition, O'Reilly), nó nói then từ khóa theo sau when các mệnh đề có thể được thay thế bằng một dòng mới hoặc dấu chấm phẩy (giống như trong if then else cú pháp). (Ruby 1.8 cũng cho phép một dấu hai chấm thay cho then... Nhưng cú pháp này không còn được cho phép trong Ruby 1.9.)


187
2018-06-04 01:20



when (-1.0/0.0)..-1 then "Epic fail" - Andrew Grimm
Đây là câu trả lời tôi đã sử dụng, bởi vì tôi định nghĩa một biến dựa trên kết quả của một chuyển đổi trường hợp. Thay vì nói type = #{score} mỗi dòng, tôi có thể chỉ cần sao chép những gì bạn đã làm. Thanh lịch hơn nhiều, tôi cũng thích một lớp lót tốt hơn nhiều (nếu có thể) - onebree


    trường hợp ... khi

Để thêm các ví dụ khác vào Câu trả lời của Chuck:

Với tham số:

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

Không có tham số:

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

Xin hãy lưu ý vấn đề mà kikito cảnh báo.


88
2017-07-05 13:19



Cảm ơn, điều này hữu ích khi có nhiều tùy chọn trên một dòng. Tôi đã cố gắng sử dụng or - sixty4bit


Nhiều ngôn ngữ lập trình, đặc biệt là các ngôn ngữ lập trình từ C, có hỗ trợ cho cái gọi là Chuyển đổi qua. Tôi đã tìm kiếm cách tốt nhất để làm điều tương tự trong Ruby và nghĩ rằng nó có thể hữu ích cho người khác:

Trong các ngôn ngữ giống như ngôn ngữ C, kiểu dáng thường trông giống như sau:

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;
}

Trong Ruby, điều tương tự cũng có thể đạt được theo cách sau:

case expression
when 'a', 'b', 'c'
  # Do something for a, b or c
when 'd', 'e'
  # Do something else for d or e
end

Điều này là không hoàn toàn tương đương, bởi vì nó không thể để cho 'a' thực hiện một khối mã trước khi đi qua 'b' hoặc là 'c', nhưng đối với hầu hết các phần tôi tìm thấy nó tương tự, đủ để có ích trong cùng một cách.


64
2017-12-07 12:11





Trong Ruby 2.0, bạn cũng có thể sử dụng lambdas trong case báo cáo, như sau:

is_even = ->(x) { x % 2 == 0 }

case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end

Bạn cũng có thể tạo các trình so sánh của riêng bạn dễ dàng bằng cách sử dụng một Struct với một tùy chỉnh ===

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

(Ví dụ được lấy từ "Procs có thể được sử dụng với các câu lệnh case trong Ruby 2.0 không?".)

Hoặc, với một lớp học hoàn chỉnh:

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

(Ví dụ được lấy từ "Làm thế nào một tuyên bố trường hợp Ruby hoạt động và những gì bạn có thể làm với nó".)


63
2017-08-01 00:04





Bạn có thể sử dụng cụm từ thông dụng, chẳng hạn như tìm loại chuỗi:

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 sẽ sử dụng toán hạng bình đẳng === cho điều này (nhờ @JimDeville). Thông tin bổ sung có sẵn tại "Ruby OperatorsĐiều này cũng có thể được thực hiện bằng cách sử dụng ví dụ @mmdemirbas (không có tham số), chỉ cách tiếp cận này là sạch hơn đối với các loại trường hợp này.


47
2017-10-16 12:17





Nếu bạn muốn biết cách sử dụng điều kiện OR trong trường hợp chuyển đổi Ruby:

Vì vậy, trong một case tuyên bố, một , là tương đương với || trong một if tuyên bố.

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

Nhiều thứ khác bạn có thể làm với câu lệnh Ruby case


29
2017-07-03 06:46