Jak zmniejszyć przełącznik w instrukcji switch?

9

Dlatego tworzę metodę tworzenia linii powitania opartej na dwóch osobach z bazy danych.

Istnieją cztery parametry: dwie nazwy ( name1i name2) oraz dwie płcie ( genderi gender2).

Dla każdej kombinacji płci mam coś innego.

Na przykład: jeśli płeć 1 to M(mężczyzna) i płeć 2 również M, wynik powinien wyglądać następująco:

Dear Sir name1 and Sir name2,

W tej chwili mój przełącznik wygląda następująco:

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.
}

Zauważ, że mam wiele opcji związanych z płcią, jak 'R'dla "Dear Relation"a niektóre bardziej, że nie mają czasu na tłumaczenie.

Jak mogę zmniejszyć tę instrukcję podwójnego przełączania?

Umieszczenie drugiego przełącznika w metodzie nie jest opcją, ponieważ istnieje również przypadek, w którym obie nazwy są takie same, a następnie dane wyjściowe należy połączyć w następujący sposób: "Dear Sir and Madame name1,"

moffeltje
źródło
1
Jeśli Twój język na to pozwala, włącz wyrażenie różniące się obiema wartościami, np gender1+gender2.
Kilian Foth,
3
W niezwiązanym z tym tytułem żeński tytuł Madamnie jest Madame. Madamejest francuską formą.
rojomoke
3
Nieco niepotrzebne, ale fakt, że twoją zmienną „płeć” może być „mężczyzna”, „kobieta” lub „relacja” jest nieco niepokojący ...
Paddy
4
„Zauważ, że mam wiele opcji płci” Cóż, to z pewnością jest obecnie modne ...
Lekkość

Odpowiedzi:

32

Dodaj tytuł do parametrów 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);

przełącznik można wyodrębnić do własnej funkcji w celu ponownego użycia i zwartości.

maniak zapadkowy
źródło
1
To czasem działa, a czasem nie ...
Deduplicator
4
@Deduplicator Zrób to domyślnie i osobno obsługuj wyjątkowe przypadki.
Val
17
… I uczyń tę funkcję genderToTitle, abyś nie musiał jej powtarzać? (Lub użyj pętli)
Bergi
18

Radykalne rozwiązanie: pozwól użytkownikowi określić własny tytuł (ze wstępnie zdefiniowanej listy, którą podajesz).

Twoje rozwiązanie (patrząc z angielskich oczu) wydaje się służyć wyłącznie Lordom („Sir”) i kobietom; większość mężczyzn byłaby nazywana „panem”, większość kobiet to „panna”, „pani” lub „pani”, w zależności od ich stanu cywilnego i osobistych opinii. Potem jest cała masa innych wyróżnień opartych na zawodowych rankingach - „Lekarze”, „Profesorowie”, „Wielebni”, a nawet, jeśli czujecie się bardzo optymistycznie na temat swojej witryny, „Świętość”!

Prostsze rozwiązanie: potrzebujesz [pojedynczej] funkcji, aby przetłumaczyć „płeć” na honorową. Wpisz go raz i zadzwoń do obu osób:

printf("Dear %s %s and %s %s" 
   , getTitle( gender1 ), name1 
   , getTitle( gender2 ), name2 
   ) ; 
Phill W.
źródło
Problem w tym, że: Nie mam żadnej kontroli nad bazą danych. ale dziękuję za dodatkowe informacje, doceniam to :)
moffeltje
8
Dear Sirjako forma adresu jest całkowicie akceptowalna dla wszystkich mężczyzn. Zgadzam się, że jako tytuł Sir (jak w in. Sir Phill) Powinien być ograniczony do rycerzy (nie panów), ale to inna sprawa.
rojomoke
1
Nie rozumiem, jak to wymagałoby dostępu do bazy danych. To jest dla mnie najczystsza metoda tego. Istnieją inne ładne redukcje przełączników, ale jest to najczystszy zamiennik, a także ładnie modulujący logikę.
Dan
4
@rojomoke Nie, to nie jest inna sprawa. To pytanie dotyczy „Szanowny Panie (wstaw tutaj nazwę)”, a nie zwykłego „Szanowny Panie”. „Szanowny Panie (tu wstawić nazwę)” jest za pomocą „Sir” jako tytuł.
hvd
Strona rejestracyjna osób często podróżujących BA, może około 2003 r., Miała „swoją świętość” na rozwijanej liście tytułów. Nadal działa na wszystko, co wiem. Pamiętam, ponieważ lista rozwijana była tak długa, że ​​spowodowała awarię przenośnej przeglądarki, którą integrowaliśmy. Polecam wolne pole, z tym wyjątkiem, że BA w szczególności prawdopodobnie konsultuje się z Debrettem i zna różne formy każdego tytułu dla różnych kontekstów (inny adres koperty i pozdrowienie jako minimum)
Steve Jessop
9

Tytuły naprawdę należą do bazy danych, ale stwierdziłeś, że nie masz nad tym kontroli. Nie określono znacznika języka, ale jego składnia należy do rodziny C, więc będzie to pseudokod, który ma prawie C ++:

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

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

Zaletą tego jest zakopanie logiki wyboru w strukturze danych zamiast w strukturze kodu: jest to podobne do delegowania do bazy danych i jest bardziej elastyczne. Jeśli trzymasz tę mapę gdzieś jako stałą statyczną, możesz prawie użyć jej jak bazy danych: staje się ona pojedynczą strukturą do aktualizacji, z której można korzystać w wielu miejscach w kodzie bez potrzeby pisania więcej kodu.


źródło
To może być dobry pomysł, aby przejść z C ++ 11 inicjatora składni, i czyni go static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. Cóż, można pominąć const, jeśli modyfikacja powinna być dozwolona.
Deduplicator
@Deduplicator zdecydowanie jest lepszy sposób. Chciałem tutaj uprościć, ponieważ nie ma znacznika językowego, ale wygląda jak C ++. Ale masz rację, zakładając, że C ++ 11.
3

Odpowiedź zapadkowy Freak jest to całkiem dobry pomysł, jeśli zdania są wszyscy ten sam wzór, lecz z dwoma wypustkami, po jednym zależy tylko od gender1odpowiedniego gender2.

Odpowiedź Phila W. jest prawdopodobnie najbardziej elastyczną odpowiedzią, ponieważ umożliwia wyraźną kontrolę nad powitaniem, choć jest całkiem poprawny, to radykalna zmiana. Być może nie masz danych w tej formie.

Odpowiedź Kiliana Fotha jest prawdopodobnie najlepsza na zadane pytanie, choć zależy on od włączenia łańcucha, co może być niemożliwe lub przynajmniej droższe.

Udoskonalenie odpowiedzi Kiliana polega na obliczeniu jednej wartości z obu danych wejściowych i włączeniu:

// 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

Oczywiście, ponieważ otrzymujesz wszystkie cztery dane wejściowe (2 nazwiska i 2 płcie) z bazy danych, dodanie kolejnej tabeli i dołączenie do niej w celu uzyskania odpowiedniego powitania jest prawdopodobnie bardziej elastyczne i może łatwiejsze niż powyższe.

Deduplikator
źródło
2

Jeśli twój język to pozwala, możesz pisać

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

Niekoniecznie jest lepsza niż twoja wersja, ponieważ nadal występuje powielanie, ale pozwala uniknąć zagnieżdżenia switch.

Kilian Foth
źródło
5
Jeśli to zrobisz, na miłość babeczek umieść to w tablicy lub czymś innym i pozbądź się przełącznika ... pozdrowienie ['MM'] = "Szanowni Państwo"; pozdrowienie [„MF”] = „Droga Pani i Sir”; pożądane Salutacja = powitanie [płeć1 + płeć2];
JDT
1
Słownik @JDT ?
komara
To, co nazwać, zależy dokładnie od języka, ale w zasadzie zbiór kluczy i wartości, tak.
JDT
1
Jest pewne udoskonalenie tego, które działa w prawie każdym języku: oblicz jedną liczbę całkowitą z obu znaków wejściowych i włącz ją, a nie ciąg.
Deduplicator
0

Zazwyczaj chciałbyś, aby ciągi interfejsu użytkownika takie jak ten były pobierane z tabeli ciągów zamiast na stałe zakodowane w kodzie źródłowym, w celu lokalizacji i łatwości aktualizacji. Podejście, które wybrałbym, to wykorzystanie danych wejściowych do zbudowania klucza odnośnika, więc coś w stylu:

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

Inne sugestie dotyczące pozwalania użytkownikom wybierać własne tytuły są ważne, jeśli masz możliwość uzyskania tych informacji. Nadal używałbym wyszukiwania tabeli ciągów w rozwiązaniu.

bmm6o
źródło