2012-04-17 4 views
222

Najlepszym sposobem mogę opisać to, co szukam jest pokazanie wam powiodło kod próbowałam dotąd:case z wielu wartości w każdym „kiedy” zablokować

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

mam Wystąpiło około 4 lub 5 różnych sytuacji, które powinny być wywołane przez około 50 różnych możliwych wartości car. Czy istnieje sposób, aby to zrobić z blokami case lub czy powinienem spróbować potężnego bloku if?

Odpowiedz

486

W oświadczeniu case, , jest odpowiednikiem || w instrukcji if.

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

Some other things you can do with a Ruby case statement

+0

Wielki Link, dzięki! – Nick

+1

[Ten link] (http://ilikestuffblog.com/2008/04/15/how-to-write-case-switch-statements-in-ruby/) ma lepsze podsumowanie instrukcji case w Ruby (i obejmuje przykłady składni regexp i splat). – rsenna

+0

Nie wiem dlaczego, ale ta dziwna sytuacja dzieje: Kiedy piszę te słowa: 'kiedy„Toyota”,„lexus”', uzyskać: 'nieoczekiwany tSTRING_BEG, oczekując keyword_do lub„{”lub ' (”(SyntaxError)' jednak, gdy piszę te słowa:.... 'kiedy "Toyota", "lexus"', działa Jedyną różnicą jest to miejsce po przecinku –

77

Można skorzystać z Rubiego "ikona" lub spłaszczenie składnię.

To sprawia, że ​​przerośnięte klauzule when - masz około 10 wartości do przetestowania na oddział, jeśli rozumiem poprawnie - trochę bardziej czytelny według mnie. Ponadto można zmodyfikować wartości do przetestowania w środowisku wykonawczym. Na przykład:

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 

Innym powszechnym rozwiązaniem byłoby użyć skrótu jak stół wysyłkowego, z klawiszami dla każdej wartości car i wartości, które są wymagalne jakiś przedmiot enkapsulacji kodu, który chcesz wykonać.

+0

Zdecydowanie bardziej czytelny w przypadku @ Nicka. (Żadna gra słów nie jest przeznaczona) –

+0

Właśnie tego użyłem, chociaż źle się czuję, że zabrałem komuś znak kontrolny: D – Nick

+0

Wspaniałe rozwiązanie dla długich linii 'kiedy'. Dziękuję za udostępnienie. – Pistos

0

Kolejny dobry sposób, aby umieścić swoją logikę w danych jest mniej więcej tak:

# 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 
Powiązane problemy