Case statement with multiple values in each 'when' block

Ruby on-RailsRubySyntaxSwitch Statement

Ruby on-Rails Problem Overview


The best way I can describe what I'm looking for is to show you the failed code I've tried thus far:

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

I've got about 4 or 5 different when situations that should be triggered by approximately 50 different possible values of car. Is there a way to do this with case blocks or should I try a massive if block?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

In a case statement, a , is the equivalent of || in an if statement.

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

Some other things you can do with a Ruby case statement

Solution 2 - Ruby on-Rails

You might take advantage of ruby's "splat" or flattening syntax.

This makes overgrown when clauses — you have about 10 values to test per branch if I understand correctly — a little more readable in my opinion. Additionally, you can modify the values to test at runtime. For example:

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

Another common approach would be to use a hash as a dispatch table, with keys for each value of car and values that are some callable object encapsulating the code you wish to execute.

Solution 3 - Ruby on-Rails

Remember switch/case (case/when, etc.) is just comparing values. I like the official answer in this instance for a simple or'd string list comparison, but for more exotic conditional / matching logic,

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

Solution 4 - Ruby on-Rails

Another nice way to put your logic in data is something like this:

# 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

Solution 5 - Ruby on-Rails

you could do something like this (inspired by @pilcrow's answer):

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

Solution 6 - Ruby on-Rails

In a case statement, equivalent of && in an if statement.

case coding_language when 'ror' && 'javascript' # code end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNickView Question on Stackoverflow
Solution 1 - Ruby on-RailsCharles CaldwellView Answer on Stackoverflow
Solution 2 - Ruby on-RailspilcrowView Answer on Stackoverflow
Solution 3 - Ruby on-RailsPedView Answer on Stackoverflow
Solution 4 - Ruby on-RailsHew WolffView Answer on Stackoverflow
Solution 5 - Ruby on-RailsMatheus PortoView Answer on Stackoverflow
Solution 6 - Ruby on-RailsShubham ChauhanView Answer on Stackoverflow