switch 문에서 스위치를 줄이는 방법은 무엇입니까?


9

그래서 데이터베이스에서 두 사람을 기반으로 인사말 줄을 만드는 방법을 만들고 있습니다.

두 개의 이름 ( name1name2)과 두 개의 성별 ( gendergender2)의 네 가지 매개 변수가 있습니다 .

모든 성별 조합에 대해, 나는 다른 결과를 가지고 있습니다.

예를 들어, 성별 1이 M(man)이고 성별 2도 M이면 출력은 다음과 같아야합니다.

Dear Sir name1 and Sir name2,

현재 내 스위치는 다음과 같습니다.

switch(gender1){
    case 'M':
        switch(gender2){
            case 'M': printf("Dear Sir %s and Sir %s", name1, name2); break;
            case 'W': printf("Dear Sir %s and Madame %s", name1, name2); break;
            case 'R': ...
        }
        break;
    case 'W':
        switch(gender2){
            case 'M': printf("Dear Madame %s and Sir %s", name1, name2); break
            case 'W': printf("Dear Madame %s and Madame %s", name1, name2); break;
            case 'R': ...
        }
        break;
    case ...etc.
}

내가 좋아하는, 여러 성 옵션이 있습니다 'R'에 대한 "Dear Relation"좀 더 내가 번역 할 시간이 없다고합니다.

이 이중 스위치 문을 어떻게 줄일 수 있습니까?

두 번째 스위치를 메소드에 넣는 것은 옵션이 아닙니다. 두 이름이 동일한 경우 출력이 다음과 같이 결합되어야하기 때문입니다. "Dear Sir and Madame name1,"



1
언어에서 허용하는 경우 값 이 서로 다른 표현식을 켭니다 ( 예 :) gender1+gender2.
Kilian Foth

3
관련이없는 점에서 여성의 제목은 여기에 사용 Madam하지 Madame. Madame프랑스 양식입니다.
rojomoke

3
약간 불필요하지만, '성별'변수가 '남성', '여성'또는 '관계'일 수 있다는 사실은 약간 혼란 스럽습니다.
Paddy

4
"여러 가지 성별 옵션이 있다는 점에 유의하십시오" 글쎄요, 요즘 유행하고 있습니다.
궤도에서 가벼운 경주

답변:


32

printf의 매개 변수에 제목을 추가하십시오.

char* title1;
switch(gender1){
    case 'M':
        title1 = "Sir";
        break;
    case 'W':
       title1 = "Madam";
        break;
    case ...etc.
}
char* title2;
switch(gender2){
    case 'M':
        title2 = "Sir";
        break;
    case 'W':
       title2 = "Madam";
        break;
    case ...etc.
}
printf("Dear %s %s and %s %s", title1, name1, title2, name2);

재사용 성과 컴팩트 성을 위해 스위치를 자체 기능으로 추출 할 수 있습니다.


1
때로는 작동하지 않을 수도 있습니다.
Deduplicator

4
@Deduplicator 기본적으로 그렇게하고 예외적 인 경우를 별도로 처리하십시오.
Val

17
genderToTitle반복 할 필요가없는 기능을 만드 시겠습니까? (또는 루프를 사용하십시오)
Bergi

18

과격한 해결책 : 사용자가 제공 한 사전 정의 된 목록에서 자신 제목을 지정하게하십시오 .

당신의 해결책 (영어 눈으로 볼 때)은 오직 주님 ( "Sir")과 숙녀들을위한 것입니다. 대부분의 남성은 결혼 상태와 개인적 의견에 따라 "Mr", 대부분의 여성은 "Miss", "Mrs"또는 "Ms"로 표시됩니다. 그런 다음 "의사", "교수", "교직자", 심지어 "거룩함"이라는 사이트에 대해 매우 낙관적 인 느낌 드는 경우에도 전문적인 순위를 기반으로하는 수많은 다른 명예가 있습니다 !

더 간단한 해결책 : "성별"을 명예롭게 번역하려면 [단일] 기능이 필요합니다. 한 번만 코딩하고 두 사람 모두에게 전화하십시오.

printf("Dear %s %s and %s %s" 
   , getTitle( gender1 ), name1 
   , getTitle( gender2 ), name2 
   ) ; 

여기에 문제가 있습니다 : 나는 데이터베이스를 전혀 제어 할 수 없습니다. 그러나 추가 정보에 감사드립니다. :)
moffeltje

8
Dear Sir주소 형식으로 모든 남성에게 완벽하게 허용됩니다. 나는 제목 으로 (에서와 같이 Sir Phill) 선생님이 ( 주가 아닌) 기사로 제한되어야 한다는 데 동의 하지만 이는 다른 문제입니다.
rojomoke

1
이것이 데이터베이스에 액세스하는 방법을 보지 못했습니다. 이것은 나에게 가장 깨끗한 방법입니다. 다른 멋진 스위치 감소가 있지만 이것은 가장 깨끗한 교체이며 논리를 훌륭하게 변조합니다.
Dan

4
@rojomoke 아니오, 그것은 다른 문제가 아닙니다. 이 질문은 "친애하는 선생님"이 아니라 "친애하는 선생님 (이름 입력)"에 관한 것입니다. "친애하는 선생님 (이름 입력)" "Sir"을 제목으로 사용하고 있습니다.
hvd

2003 년경 BA 상용 고객 가입 페이지의 제목 드롭 다운 목록에 "거룩함"이있었습니다. 아직도 내가 아는 전부를 위해한다. 드롭 다운이 너무 길어서 통합중인 휴대용 브라우저와 충돌했기 때문에 기억합니다. 나는 특히 그 BA를 제외하고 무료로 필드를 권하고 싶습니다 아마 Debrett의 자문과 (최소한 다른 봉투 주소와 인사말) 다른 컨텍스트에 대한 각 타이틀의 다양한 형태를 알고
스티브 Jessop

9

제목은 실제로 데이터베이스에 속하지만 제어 할 권한이 없다고 언급했습니다. 언어 태그를 지정하지 않았지만 구문은 C 제품군에 있으므로 거의 C ++ 인 유사 코드가됩니다.

map<string, string> titles;
titles.emplace("M", "Sir");
titles.emplace("F", "Madam");

cout << "Dear " << titles[gender1] << " " << name1 << " and "
     << titles[gender2] << " " << name2 << endl;

이것의 장점은 선택 논리를 코드 구조가 아닌 데이터 구조에 묻는 것입니다. 이는 데이터베이스에 위임하는 것과 유사하며 더 유연합니다. 맵을 어딘가에 정적 상수로 유지하면 거의 데이터베이스처럼 사용할 수 있습니다 . 더 많은 코드 를 작성할 필요없이 코드의 여러 위치에서 사용할 수있는 단일 구조가 업데이트됩니다 .



C ++ 구문 초기화 (11)와 함께 갈 수있는 좋은 생각, 그리고 그것을 만드는 수 static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. 글쎄, const수정이 허용되어야한다면 밖으로 나갈 수 있습니다.
중복 제거기

@ 중복 제거기는 확실히 더 좋은 방법이 있습니다. 언어 태그가 없지만 C ++처럼 보입니다 . 그러나 C ++ 11을 가정하면 정확합니다.

3

문장이 모두 같은 패턴이지만 두 개의 삽입이있는 경우 gender1각각에 의존하는 래칫 괴물의 대답 은 꽤 좋은 생각 입니다 gender2.

Phil W.의 답변 은 인사말을 명시 적으로 제어 할 수 있기 때문에 가장 유연한 답변 일 것입니다. 그러나 근본적인 변화는 맞습니다. 해당 형식의 데이터가 없을 수 있습니다.

Kilian Foth의 대답 은 아마도 질문에 대한 최선 의 대답 일 것입니다. 그러나 문자열을 전환하는 데 의존하지만 가능하지 않거나 적어도 더 비쌉니다.

Kilian의 답변을 개선하면 두 입력에서 단일 값을 계산하고 다음을 켜는 것입니다.

// Using a macro in C for readability. C++ would use a constexpr function
#define COMBINE(a, b) ((a<<CHAR_BIT)+b)

switch( COMBINE(gender1, gender2)) {
  case COMBINE('M', 'M'): 
    print "Dear Sirs";
    break;
  case COMBINE('M', 'F'): 
  case COMBINE('F', 'M'): 
    print "Dear Sir and Madam";
    break;
  ...
#undef COMBINE

물론, 데이터베이스에서 4 개의 입력 (2 개의 이름과 2 개의 성별)을 모두 얻을 때 다른 테이블을 추가하고 그에 합류하여 적절한 인사말을 얻는 것이 위의 것보다 더 유연하고 쉬울 것입니다.


2

당신의 언어로 할 수 있다면, 쓸 수 있습니다

switch(gender1+gender2) {
  case "MM": 
    print "Dear Sirs";
    break;
  case "MF": 
  case "FM":
    print "Dear Sir and Madam";
    break;
  ...

여전히 복제가 있기 때문에 반드시 버전보다 낫지 는 않지만 중첩은 피하십시오 switch.


5
이렇게하면 컵케익을 사랑하기 위해 이것을 어레이나 무언가에 넣고 스위치를 제거하십시오 .... salutation [ 'MM'] = "Dear Sirs"; 인사말 [ 'MF'] = "친애하는 부인과 선생님"; 원하는 황산염 = 경례 [성별 1 + 성별 2];
JDT

1
@JDT 사전 ?
gnat

전화해야 할 것은 언어에 따라 다르지만 기본적으로 키와 값의 모음입니다.
JDT

1
거의 모든 언어에서 작동하는 약간의 개선이 있습니다. 두 입력 문자에서 단일 정수를 계산하고 문자열이 아닌 스위치를 켜십시오.
중복 제거기

0

지역화 및 업데이트 용이성을 위해 일반적으로 소스 코드에 하드 코딩 된 대신 문자열 테이블에서 이와 같은 UI 문자열을 가져 오기를 원합니다. 그래서 내가 취할 접근법은 입력을 사용하여 조회 키를 작성하는 것입니다.

var lookupKey = "SALUTATION_" + gender1 + "_" + gender2;
var format = GetLocalizedString(lookupKey);
printf(format, name1, name2);

정보를 얻을 수있는 기회가 있다면 사용자가 자신의 타이틀을 선택할 수 있도록하는 다른 제안이 유효합니다. 여전히 솔루션에서 문자열 테이블 조회를 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.