각 '언제'블록에 여러 값이있는 사례 설명


314

내가 찾고있는 것을 설명하는 가장 좋은 방법은 지금까지 시도한 실패한 코드를 보여주는 것입니다.

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

when약 50 가지의 가능한 값으로 트리거되어야하는 약 4 ~ 5 가지 상황이 있습니다 car. case블록 으로이 작업을 수행 할 수 if있습니까? 아니면 대규모 블록을 시도해야 합니까?

답변:


669

A의 case문, a는 ,것과 같습니다 ||if문.

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

루비 사례 진술로 할 수있는 다른 일들


1
이 링크 에는 Ruby의 case 문이 더 잘 요약되어 있습니다 (regexp 및 splat 구문의 예제도 포함).
rsenna

나는 왜 그런지 모르겠지만,이 이상한 상황이 발생한다 : 이것을 쓸 때 : when "toyota", "lexus", 나는 얻는다 : unexpected tSTRING_BEG, expecting keyword_do or '{' or '(' (SyntaxError). 그러나 이것을 when "toyota","lexus"쓰면 작동합니다. 유일한 차이점은 쉼표 뒤에 공백입니다.
Furkan Ayhan

@FurkanAyhan 그것은 이상하다. 계속 해서 코드를 테스트하여 작동하는지 확인했습니다. 내 생각에 코드에 다른 오류가 발생하는 것 같습니다. 어딘가에서 그런 식으로 문자열을 닫는 것을 잊었습니까?
Charles Caldwell

1
글쎄, 이것은 작동하지만 루비가 프로그래머의 편의에 중점을두면 왜 표준을 지원하지 않는지 궁금합니다. 또는 '또는'? 혼란스러워
Zia Ul Rehman Mughal

2
루비는 지원하지 않습니다 or또는 ||(가) 때문에 여기에 when그것의 권리가 아닌 하나의 식별자에 쉼표로 구분 된 일련의 표현식을합니다. 당신이 있다면이 때문에 when a or b,이는 동등한로한다인지 분명하지 않다 when a, b또는 when (a or b)표현식을 평가 후자있는, a or b경우에 그것을 던지기 전에 먼저. 문맥에 따라 행동을 바꾸는 토큰을 언어가 처리하는 것이 더 놀랍고 다루기 쉽지 않으며, 그때 or오른쪽에 실제 표현 을 사용할 수 없습니다 .
Taywee

99

루비의 "splat"또는 flattening 구문을 활용할 수 있습니다.

이것은 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

무례하다는 뜻은 아니지만 시간과 공간 모두에서 효율성이 떨어지기 때문에 하향 조정되었습니다. 또한 다른 두 가지 대답보다 더 복잡하고 읽기 쉽습니다. 이 방법을 사용하면 어떤 이점이 있습니까?
Nick

전체 분류를 하나의 객체로 만듭니다. 이제 해당 개체를 직렬화하여 다른 사람에게 보내서 논리를 설명하거나 데이터베이스에 저장하고 사람들이 편집 할 수 있도록하는 등의 작업을 수행 할 수 있습니다. (새로운 자동차 모델이 나오면 곧 논리가 바뀔 것입니다.) "테이블 중심"을 찾아 볼 수 있습니다.
휴 울프

YAGNI ( "필요하지 않습니다")가 여기에 적용될 수 있습니다. 이 디자인은 미래에는 존재하지만 아직 존재하지 않는 시나리오의 시간 / 공간 효율성과 가독성을 희생합니다. 비용은 지금 지불되지만 보상은 절대 얻을 수 없습니다.
Nick
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.