409 Stimmen

Case-Anweisung mit mehreren Werten in jedem 'when'-Block

Am besten kann ich beschreiben, wonach ich suche, indem ich Ihnen den fehlgeschlagenen Code zeige, den ich bisher ausprobiert habe:

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

Ich habe etwa 4 oder 5 verschiedene when Situationen, die durch etwa 50 verschiedene mögliche Werte ausgelöst werden sollten car . Gibt es eine Möglichkeit, dies zu tun mit case Blöcke oder sollte ich eine massive if Block?

884voto

Charles Caldwell Punkte 15869

In einem case Anweisung, eine , ist das Äquivalent zu || in einem if Erklärung.

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

Einige andere Dinge, die Sie mit einer Ruby case-Anweisung tun können

122voto

pilcrow Punkte 53851

Sie könnten die "Splat"- oder Flattening-Syntax von Ruby nutzen.

Dies macht überwucherte when Klauseln - Sie haben etwa 10 Werte pro Verzweigung zu testen, wenn ich richtig verstehe - ein wenig mehr lesbar meiner Meinung nach. Außerdem können Sie die zu testenden Werte zur Laufzeit ändern. Zum Beispiel:

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

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

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

Ein anderer üblicher Ansatz wäre die Verwendung eines Hashes als Versandtabelle, mit Schlüsseln für jeden Wert von car und Werte, bei denen es sich um ein aufrufbares Objekt handelt, das den Code kapselt, den Sie ausführen möchten.

3voto

Ped Punkte 29

Denken Sie daran, dass switch/case (case/when, usw.) nur ein Vergleich ist Werte . Ich mag die offizielle Antwort in diesem Fall für eine einfache oder'd String-Liste Vergleich, aber für mehr exotische bedingte / Matching-Logik,

case true
  when ['honda', 'acura'].include?(car)
    # do something
  when (condition1 && (condition2 || condition3))
    # do  something different
  else
    # do something else
end

0voto

Hew Wolff Punkte 1491

Eine andere gute Möglichkeit, Ihre Logik in Daten zu verpacken, ist etwa die folgende:

# 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

0voto

Matheus Porto Punkte 159

Könnte man so etwas machen (inspiriert von @pilcrows Antwort):

honda  = %w[honda acura civic element fit ...]
toyota = %w[toyota lexus tercel rx yaris ...]

honda += %w[ev_ster concept_c concept_s ...] if include_concept_cars

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X