在每个“ when”块中具有多个值的case语句


314

我能描述我所寻找的最好方法是向您展示到目前为止我尝试过的失败代码:

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

我有大约4或5种不同的when情况,应该由的大约50种不同的可能值触发car。有没有办法用case积木做到这一点,还是应该尝试大量if积木?

Answers:


669

case声明中,一个,是相当于||if声明。

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

Ruby case语句可以执行的其他操作


1
该链接对Ruby中的case语句有一个更好的总结(并且还包括regexp和splat语法的示例)。
rsenna

我不知道为什么,但是会发生这种奇怪的情况:当我写这个:时when "toyota", "lexus",我得到:unexpected tSTRING_BEG, expecting keyword_do or '{' or '(' (SyntaxError)。但是,当我编写此代码时:when "toyota","lexus",它可以工作。唯一的区别是逗号后有一个空格。
Furkan Ayhan 2014年

@FurkanAyhan这很奇怪。我继续并测试了代码,以确保它确实有效。我的猜测是您的代码中还有其他事情正在发生,从而导致了类似的错误。您是否有可能忘记在某个地方或类似位置关闭字符串?
Charles Caldwell 2014年

1
很好,这可行,但是当ruby专注于程序员的轻松时,我想知道为什么它不支持标准||。或“或”?这有点令人迷惑
Zia Ul Rehman Mughal

2
红宝石不支持or||在这里是因为when采取了一系列逗号分隔的表达式来它的权利,而不是一个单一的标识符。因此,如果您有when a or b,则不清楚是否将其视为when a, b或的等效项 when (a or b),后者将a or b首先将表达式求值,然后再将其放入when中。使该语言具有基于上下文更改行为的令牌,这更令人惊讶且不那么容易处理,然后您将无法在orwhen的右侧使用真实的表达式。
Taywee

99

您可能会利用ruby的“ splat”或扁平化语法。

这会使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

另一种常见的方法是将散列用作调度表,其中每个键的值car和键值是一些可调用对象,这些键封装了您希望执行的代码。


这是我最终使用的,尽管我很难过拿走别人的校验标记:D
Nick

长线的出色解决方案when。感谢分享。
Pistos

0

将逻辑放入数据中的另一种好方法是:

# 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

我并不是无礼的,但是我不赞成这样做,因为这在时间和空间上都效率较低。与其他两个答案相比,它也更复杂且可读性更差。使用这种方法的好处是什么?
尼克,

它将您的整个分类放在一个对象中。您现在可以使用该对象执行操作,例如对其进行序列化并将其发送给其他人以解释您的逻辑,或者将其存储在数据库中并允许人们对其进行编辑。(当新车型问世时,逻辑将很快改变,对吗?)您可能会查找“表格驱动”。
希尔·沃尔夫

YAGNI(“您不需要它”)可以在这里申请。对于将来可能存在但尚不存在的方案,设计牺牲了时间/空间效率和可读性。现在就已经支付了费用,但是可能永远不会获得奖励。
尼克,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.