2012-04-17 6 views
222

Cách tốt nhất mà tôi có thể mô tả những gì tôi đang tìm kiếm là để hiển thị cho bạn mã thất bại tôi đã cố gắng cho đến nay:tuyên bố Case với nhiều giá trị trong mỗi 'khi' chặn

case car 
    when ['honda', 'acura'].include?(car) 
    # code 
    when 'toyota' || 'lexus' 
    # code 
end 

Tôi đã có khoảng 4 hoặc 5 trường hợp khác nhau when cần được kích hoạt bởi khoảng 50 giá trị có thể khác nhau của car. Có cách nào để làm điều này với các khối case hoặc tôi nên thử một khối lớn if không?

Trả lời

486

Trong tuyên bố case, số , tương đương với || trong tuyên bố if.

case car 
    when 'toyota', 'lexus' 
     # code 
end 

Some other things you can do with a Ruby case statement

+0

lớn liên kết, cảm ơn! – Nick

+1

[Liên kết này] (http://ilikestuffblog.com/2008/04/15/how-to-write-case-switch-statements-in-ruby/) có tóm tắt tốt hơn về các câu lệnh trong Ruby (và nó bao gồm ví dụ về cú pháp regexp và splat). – rsenna

+0

Tôi không biết tại sao, nhưng tình huống kỳ lạ này xảy ra: Khi tôi viết điều này: 'khi" toyota "," lexus "', Tôi nhận được: 'unexpected tSTRING_BEG, expected keyword_do or '{' or ' ('(Lỗi Cú pháp) ' Tuy nhiên, khi tôi viết những dòng này:.... ' khi "toyota", "lexus"', nó hoạt động Sự khác biệt duy nhất là một khoảng trắng sau dấu phẩy –

77

Bạn có thể tận dụng lợi thế của "splat" ruby ​​hoặc làm phẳng cú pháp.

Điều này làm cho các điều khoản quá mức when - bạn có khoảng 10 giá trị để kiểm tra trên mỗi chi nhánh nếu tôi hiểu chính xác - có thể đọc được một chút theo ý kiến ​​của tôi. Ngoài ra, bạn có thể sửa đổi các giá trị để kiểm tra khi chạy. Ví dụ:

honda = ['honda', 'acura', 'civic', 'element', 'fit', ...] 
toyota = ['toyota', 'lexus', 'tercel', 'rx', 'yaris', ...] 
... 

if include_concept_cars: 
    honda += ['ev-ster', 'concept c', 'concept s', ...] 
    ... 

case car 
when *toyota 
    # Do something for Toyota cars 
when *honda 
    # Do something for Honda cars 
... 
end 

Một phương pháp phổ biến sẽ được sử dụng một hash như một bảng công văn, với các phím cho mỗi giá trị của car và giá trị mà một số đối tượng có thể được gọi đóng gói mã bạn muốn thực hiện.

+0

Chắc chắn dễ đọc hơn trong trường hợp của Nick @. (Không có ý định chơi chữ) –

+0

Đây là những gì tôi đã kết thúc bằng cách sử dụng, mặc dù tôi cảm thấy xấu lấy đi dấu kiểm của ai đó: D – Nick

+0

Giải pháp sáng chói cho các dòng 'khi' dài. Cám ơn vì đã chia sẻ. – Pistos

0

Một cách tốt đẹp để đưa logic của bạn trong dữ liệu là một cái gì đó như thế này:

# Initialization. 
CAR_TYPES = { 
    foo_type: ['honda', 'acura', 'mercedes'], 
    bar_type: ['toyota', 'lexus'] 
    # More... 
} 
@type_for_name = {} 
CAR_TYPES.each { |type, names| names.each { |name| @type_for_name[type] = name } } 

case @type_for_name[car] 
when :foo_type 
    # do foo things 
when :bar_type 
    # do bar things 
end