Wie reduziere ich einen Schalter in einer switch-Anweisung?

9

Also mache ich eine Methode, um eine Anrede zu erstellen, die auf zwei Personen aus einer Datenbank basiert.

Es gibt vier Parameter: die beiden Namen ( name1und name2) und die beiden Geschlechter ( genderund gender2).

Für jede Geschlechtskombination habe ich eine andere Ausgabe.

Zum Beispiel: Wenn Geschlecht 1 M(Mann) und Geschlecht 2 auch ist M, sollte die Ausgabe ungefähr so ​​aussehen:

Dear Sir name1 and Sir name2,

Zu diesem Zeitpunkt sieht mein Schalter folgendermaßen aus:

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

Beachten Sie, dass ich mehrere Geschlechtsoptionen habe, z. B. 'R'für "Dear Relation"und einige andere, für deren Übersetzung ich keine Zeit habe.

Wie kann ich diese Double-Switch-Anweisung reduzieren?

Das Einfügen des zweiten Schalters in eine Methode ist keine Option, da es auch einen Fall gibt, in dem beide Namen gleich sind und die Ausgabe dann wie folgt kombiniert werden sollte: "Dear Sir and Madame name1,"

moffeltje
quelle
1
Wenn Ihre Sprache dies zulässt, schalten Sie einen Ausdruck ein, der mit beiden Werten variiert , z gender1+gender2.
Kilian Foth
3
In einem nicht verwandten Punkt ist der hier zu verwendende weibliche Titel Madamnicht Madame. Madameist die französische Form.
Rojomoke
3
Etwas unnötig, aber die Tatsache, dass Ihre 'Geschlechts'-Variable' männlich ',' weiblich 'oder' Beziehung 'sein kann, ist etwas beunruhigend ...
Paddy
4
"Beachten Sie, dass ich mehrere Geschlechtsoptionen habe" Nun, das ist heutzutage sicherlich in Mode ...
Leichtigkeitsrennen im Orbit

Antworten:

32

Fügen Sie den Parametern des Drucks den Titel hinzu:

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);

Sie können den Switch für Wiederverwendbarkeit und Kompaktheit in eine eigene Funktion extrahieren.

Ratschenfreak
quelle
1
Das funktioniert manchmal, manchmal nicht ...
Deduplikator
4
@Deduplicator Tun Sie dies standardmäßig und behandeln Sie Ausnahmefälle separat.
Val
17
… Und das zu einer Funktion machen, genderToTitledamit Sie es nicht wiederholen müssen? (Oder verwenden Sie eine Schleife)
Bergi
18

Radikale Lösung: Lassen Sie den Benutzer seinen eigenen Titel angeben (aus einer von Ihnen angegebenen vordefinierten Liste).

Ihre Lösung (aus englischer Sicht) scheint nur für Lords ("Sir") und Damen zu sorgen. Die meisten Männer würden je nach Familienstand und persönlicher Meinung als "Herr", die meisten Frauen als "Fräulein", "Frau" oder "Frau" angesprochen. Dann gibt es eine ganze Reihe weiterer Ehrungen, die auf der professionellen Rangliste basieren - "Ärzte", "Professoren", "Reverends" und sogar "Heiligkeit" , wenn Sie wirklich optimistisch in Bezug auf Ihre Website sind!

Einfachere Lösung: Sie benötigen eine [einzelne] Funktion, um "Geschlecht" in eine Ehrung zu übersetzen. Codieren Sie es einmal und nennen Sie es für beide Personen:

printf("Dear %s %s and %s %s" 
   , getTitle( gender1 ), name1 
   , getTitle( gender2 ), name2 
   ) ; 
Phill W.
quelle
Das Problem hierbei ist: Ich habe keinerlei Kontrolle über die Datenbank. aber danke für Ihre zusätzlichen Informationen, schätzen Sie es :)
moffeltje
8
Dear Sirals Anrede ist für alle Männer durchaus akzeptabel. Ich stimme zu, dass Sir (wie in ) als TitelSir Phill auf Ritter (nicht Lords) beschränkt sein sollte, aber das ist eine andere Sache.
Rojomoke
1
Ich sehe nicht ein, wie dies den Zugriff auf die Datenbank erfordern würde. Dies ist für mich die sauberste Methode, dies zu tun. Es gibt andere nette Schalterreduzierungen, aber dies ist der sauberste Ersatz sowie eine schöne Modulation der Logik.
Dan
4
@rojomoke Nein, das ist keine andere Sache. Bei dieser Frage geht es um "Sehr geehrter Herr (Name hier einfügen)", nicht um ein einfaches "Sehr geehrter Herr". „Sehr geehrter Herr (Name hier)“ wird mit „Sir“ als Titel.
hvd
Die BA-Vielflieger-Anmeldeseite, vielleicht um 2003, hatte "seine Heiligkeit" in der Dropdown-Liste der Titel. Tut es immer noch, soweit ich weiß. Ich erinnere mich, weil das Dropdown-Menü so lang war, dass der von uns integrierte tragbare Browser abstürzte. Ich würde ein freies Feld empfehlen, außer dass insbesondere BA wahrscheinlich Debrett konsultiert und mehrere Formen jedes Titels für verschiedene Kontexte kennt (mindestens unterschiedliche Umschlagadresse und Anrede)
Steve Jessop
9

Titel gehören wirklich in die Datenbank, aber Sie haben angegeben, dass Sie keine Kontrolle darüber haben. Sie haben kein Sprach-Tag angegeben, aber die Syntax gehört zur C-Familie. Dies ist also ein Pseudocode, der fast C ++ ist:

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

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

Dies hat den Vorteil, dass Sie die Auswahllogik in einer Datenstruktur und nicht in einer Codestruktur vergraben: Dies ähnelt der Delegierung an die Datenbank und ist flexibler. Wenn Sie diese Karte als eine statische Konstante irgendwo halten, können Sie fast wie ein Datenbank verwenden: es wird eine einzige Struktur zu aktualisieren , die , ohne dass an vielen Stellen im Code verwendet werden können , um schreibt mehr Code.


quelle
Es könnte eine gute Idee sein, die C ++ 11-Initialisierersyntax zu verwenden und Folgendes zu erstellen static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. Nun, man kann das weglassen const, wenn das Ändern erlaubt sein sollte.
Deduplikator
@Deduplicator definitiv, es gibt einen besseren Weg. Ich wollte hier der Einfachheit halber, da es kein Sprach-Tag gibt, aber es sieht aus wie C ++. Aber Sie haben Recht, wenn Sie C ++ 11 annehmen.
3

Die Antwort des Ratschenfreaks ist eine gute Idee, wenn die Sätze alle das gleiche Muster haben, aber mit zwei Einfügungen, von denen jeweils nur eine von der gender1jeweiligen abhängig ist gender2.

Die Antwort von Phil W. ist wahrscheinlich die flexibelste, da sie eine explizite Kontrolle über die Begrüßung ermöglicht, obwohl er ganz richtig ist, dass es sich um eine radikale Änderung handelt. Möglicherweise verfügen Sie nicht über die Daten in dieser Form.

Kilian Foths Antwort ist wahrscheinlich die beste für die gestellte Frage, obwohl er darauf angewiesen ist, eine Saite einzuschalten, was möglicherweise nicht möglich oder zumindest wahrscheinlich teurer ist.

Eine Verfeinerung von Kilians Antwort besteht darin, einen einzelnen Wert aus beiden Eingaben zu berechnen und diesen einzuschalten:

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

Da Sie alle vier Eingaben (2 Namen und 2 Geschlechter) aus einer Datenbank erhalten, ist das Hinzufügen einer weiteren Tabelle und das Zusammenfügen dieser Tabellen zur Erzielung der richtigen Anrede wahrscheinlich flexibler und möglicherweise einfacher als die oben genannten.

Deduplikator
quelle
2

Wenn Ihre Sprache es Ihnen erlaubt, können Sie schreiben

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

Es ist nicht unbedingt besser als Ihre Version, da es immer noch Duplikate gibt, aber es vermeidet die verschachtelten switch.

Kilian Foth
quelle
5
Wenn Sie dies tun, setzen Sie dies aus Liebe zu Cupcakes in ein Array oder etwas anderes und entfernen Sie den Schalter .... Anrede ['MM'] = "Sehr geehrte Damen und Herren"; Anrede ['MF'] = "Sehr geehrte Damen und Herren"; gewünschte Begrüßung = Anrede [Geschlecht1 + Geschlecht2];
JDT
1
@ JDT Wörterbuch ?
Mücke
Wie man das genau nennt, hängt von der Sprache ab, aber im Grunde genommen eine Sammlung von Schlüsseln und Werten, ja.
JDT
1
Es gibt eine leichte Verfeinerung, die in nahezu jeder Sprache funktioniert: Berechnen Sie eine einzelne Ganzzahl aus beiden Eingabezeichen und schalten Sie diese ein, nicht eine Zeichenfolge.
Deduplikator
0

Normalerweise möchten Sie, dass UI-Zeichenfolgen wie diese aus einer Zeichenfolgentabelle abgerufen werden, anstatt im Quellcode fest codiert zu sein, um sie zu lokalisieren und die Aktualisierung zu vereinfachen. Der Ansatz, den ich wählen würde, wäre, die Eingaben zu verwenden, um einen Suchschlüssel zu erstellen, also so etwas wie:

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

Die anderen Vorschläge, wie Benutzer ihre eigenen Titel auswählen können, sind gültig, wenn Sie die Möglichkeit haben, diese Informationen abzurufen. Ich würde immer noch eine String-Tabellensuche in der Lösung verwenden.

bmm6o
quelle