web-dev-qa-db-ja.com

各 'when'ブロックに複数の値を持つCaseステートメント

私が探しているものを説明するための最良の方法は、これまでに試した失敗したコードを表示することです。

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

私はwhenの可能性のある約50の異なる値によって引き起こされるべきである約4または5つの異なるcar状況を持っています。これをcaseブロックで行う方法はありますか、それとも大規模なifブロックを試すべきですか?

278
Nick

caseステートメントでは、,ifステートメントの||と同等です。

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

Rubyのcase文でできることは他にもあります

601

あなたはRubyの「スプラット」あるいは平坦化構文を利用するかもしれません。

これは生い茂ったwhen節を作ります - 私が正しく理解しているなら、ブランチごとにテストする値は約10になります - 私の意見ではもう少し読みやすくなります。さらに、実行時にテストする値を変更できます。例えば:

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

もう1つの一般的な方法は、carの各値に対するキーと、実行したいコードをカプセル化する呼び出し可能オブジェクトである値を使用して、ディスパッチテーブルとしてハッシュを使用することです。

92
pilcrow

ロジックをデータに入れるもう1つの良い方法は、次のようなものです。

# 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
2
Hew Wolff