Come ridurre un interruttore in un'istruzione switch?

9

Quindi sto creando un metodo per creare una linea di saluto basata su due persone da un database.

Ci sono quattro parametri: i due nomi ( name1 e name2 ) ei due sessi ( gender e gender2 ).

Per ogni combinazione di genere, ho un tipo di output diverso.

Ad esempio: se gender 1 è M (man) e gender 2 è anche M , l'output dovrebbe essere qualcosa del tipo:

Dear Sir name1 and Sir name2,

Al momento, il mio interruttore ha il seguente aspetto:

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

Nota che ho più opzioni di genere, come 'R' per "Dear Relation" e altre ancora che non ho il tempo di tradurre.

Come posso ridurre questa dichiarazione di doppio passaggio?

L'inserimento del secondo switch in un metodo non è un'opzione perché esiste anche un caso in cui entrambi i nomi sono uguali e quindi l'output deve essere combinato come: "Dear Sir and Madame name1,"

    
posta moffeltje 14.07.2015 - 10:49
fonte

6 risposte

32

Aggiungi il titolo ai parametri di 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);

puoi estendere l'interruttore alla sua funzione per la riutilizzabilità e la compattezza.

    
risposta data 14.07.2015 - 10:56
fonte
18

Soluzione radicale: consente all'utente di specificare il proprio proprio titolo (da un elenco predefinito fornito).

La tua soluzione (vista attraverso gli occhi inglesi) sembra soddisfare solo i Lord ("Signore") e le signore; la maggior parte degli uomini verrebbe chiamata "Mr", la maggior parte delle donne come "Miss", "Mrs" o "Ms", a seconda del loro stato civile e delle opinioni personali. Poi c'è un sacco di altri onorifici basati sulla classifica professionale - "Dottori", "Professori", "Reverendi" e anche, se ti senti davvero ottimista riguardo al tuo sito, "Santità"!

Soluzione più semplice: hai bisogno di una funzione [singola] per tradurre "genere" in un onorifico. Codificalo una volta e chiamalo per entrambe le persone:

printf("Dear %s %s and %s %s" 
   , getTitle( gender1 ), name1 
   , getTitle( gender2 ), name2 
   ) ; 
    
risposta data 14.07.2015 - 14:18
fonte
9

I titoli appartengono davvero al database, ma hai affermato di non avere alcun controllo su questo. Non hai specificato un tag della lingua ma la sintassi è nella famiglia C, quindi questo sarà pseudocodice che è quasi C ++:

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

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

Il vantaggio di questo è seppellire la logica di selezione in una struttura di dati piuttosto che una struttura di codice: questo è simile alla delega al database ed è più flessibile. Se mantieni la mappa come costante statica da qualche parte, puoi quasi usarla come un database: diventa una singola struttura da aggiornare che può essere utilizzata in molti punti del codice senza bisogno di scrivi altro codice.

    
risposta data 14.07.2015 - 18:10
fonte
3

La risposta di cratchet freak è piuttosto una buona idea se le frasi sono tutte dello stesso schema, ma con due riquadri, uno ognuno dipende solo da gender1 rispettivo gender2 .

La risposta di Phil W. è probabilmente la risposta più flessibile in quanto consente un controllo esplicito sul saluto, sebbene sia abbastanza corretto è un cambiamento radicale. Potresti non avere i dati in questo formato.

La risposta di Kilian Foth è probabilmente la migliore per la domanda, anche se dipende dall'accensione di una stringa, che potrebbe non essere possibile o è probabilmente più costoso almeno.

Un raffinamento sulla risposta di Kilian è calcolare un singolo valore da entrambi gli input e accendere quello:

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

Naturalmente, dato che stai ricevendo tutti e quattro gli input (2 nomi e 2 generi) da un database, aggiungere un'altra tabella e unirti a questo per ottenere il saluto corretto è probabilmente più flessibile e forse più semplice di quanto sopra.

    
risposta data 14.07.2015 - 17:52
fonte
2

Se la tua lingua ti permette di farlo, puoi scrivere

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

Non è necessariamente migliore della tua versione, poiché c'è ancora una duplicazione, ma evita% nidificato diswitch.

    
risposta data 14.07.2015 - 11:11
fonte
0

In genere, le stringhe dell'interfaccia utente come questa vengono utilizzate da una tabella di stringhe anziché essere codificate nel codice sorgente, per la localizzazione e la facilità di aggiornamento. Quindi l'approccio che vorrei prendere sarebbe quello di utilizzare gli input per costruire una chiave di ricerca, quindi qualcosa del tipo:

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

Gli altri suggerimenti su come consentire agli utenti di selezionare i propri titoli sono validi, se si ha la possibilità di ottenere tali informazioni. Vorrei ancora utilizzare una ricerca tabella string nella soluzione.

    
risposta data 15.07.2015 - 16:52
fonte