Come ridurre uno switch in un'istruzione switch?


9

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

Esistono quattro parametri: i due nomi ( name1e name2) e i due sessi ( gendere gender2).

Per ogni combinazione di genere, ho una sorta di output diverso.

Ad esempio: se il genere 1 è M(man) e anche il genere 2 M, l'output dovrebbe essere simile a:

Dear Sir name1 and Sir name2,

In questo momento, il mio interruttore è simile al seguente:

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 alcune altre che non ho il tempo di tradurre.

Come posso ridurre questa doppia istruzione switch?

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



1
Se la tua lingua lo consente, attiva un'espressione che varia con entrambi i valori, ad es gender1+gender2.
Kilian Foth,

3
Su un punto non correlato, il titolo femminile da utilizzare qui Madamnon lo è Madame. Madameè la forma francese.
Rojomoke,

3
Leggermente non necessario, ma il fatto che la tua variabile di "genere" possa essere "maschio", "femmina" o "relazione" è un po 'inquietante ...
Paddy,

4
"Nota che ho diverse opzioni di genere" Beh, è ​​sicuramente in voga in questi giorni ...
Razze di leggerezza in orbita

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

è possibile estrarre lo switch alla propria funzione per riutilizzabilità e compattezza.


1
A volte funziona, a volte no ...
Deduplicatore,

4
@Deduplicator Fallo di default e gestisci i casi eccezionali separatamente.
Val

17
... e renderlo una funzione in genderToTitlemodo da non doverlo ripetere? (O usa un loop)
Bergi,

18

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

La tua soluzione (vista attraverso gli occhi inglesi) sembra soddisfare solo Lords ("Sir") e le donne; la maggior parte degli uomini verrebbe indirizzata come "Mr", la maggior parte delle donne come "Miss", "Mrs" o "Ms", a seconda del loro stato civile e delle opinioni personali. Poi c'è tutta una serie di altri onorifici basati su classifiche professionali: "Medici", "Professori", "Reverendi" e persino, se ti senti davvero ottimista sul tuo sito, "Santità"!

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

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

Il problema qui è: non ho alcun controllo sul database. ma grazie per le tue informazioni aggiuntive, lo apprezzo :)
moffeltje,

8
Dear Sircome forma di indirizzo è perfettamente accettabile per tutti i maschi. Sono d'accordo che come titolo , Sir (come in Sir Phill) dovrebbe essere limitato ai cavalieri (non ai signori), ma è una questione diversa.
Rojomoke,

1
Non vedo come ciò richiederebbe l'accesso al database. Questo, per me, è il metodo più pulito per farlo. Ci sono altre riduzioni interessanti dell'interruttore, ma questa è la sostituzione più pulita, oltre a modulare bene la logica.
Dan

4
@rojomoke No, non è una questione diversa. Questa domanda riguarda "Gentile Signore (inserire il nome qui)", non un semplice "Gentile Signore". "Gentile Signore (inserisci il nome qui)" sta usando "Sir" come titolo.
hvd,

La pagina di iscrizione al frequent flyer di BA, forse intorno al 2003, aveva "la sua santità" nell'elenco a discesa dei titoli. Lo fa ancora per quello che ne so. Ricordo perché il menu a discesa era così lungo che si è bloccato il browser portatile che stavamo integrando. Consiglierei un campo libero, tranne per il fatto che BA in particolare probabilmente consulta Debrett e conosce più forme di ciascun titolo per contesti diversi (indirizzo di busta e saluto diversi come minimo)
Steve Jessop,

9

I titoli appartengono davvero al database, ma hai dichiarato di non avere alcun controllo su questo. Non hai specificato un tag di 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 è che seppellisci la logica di selezione in una struttura di dati piuttosto che in una struttura di codice: è simile alla delega al database ed è più flessibile. Se mantieni quella mappa come costante statica da qualche parte, puoi quasi usarla come un database: diventa una singola struttura da aggiornare che può essere usata in molti punti del codice senza bisogno di scrivere altro codice.



Potrebbe essere una buona idea di andare con C ++ 11 inizializzatore della sintassi, e rendendolo static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. Bene, si può tralasciare la possibilità di constmodificarlo.
Deduplicatore,

@Deduplicator sicuramente, c'è un modo migliore. Stavo andando per semplicità qui dato che non esiste un tag di lingua ma sembra C ++. Ma hai ragione, assumendo C ++ 11.

3

la risposta di Ratchet Freak è piuttosto una buona idea se le frasi sono tutte dello stesso schema, ma con due inserti, uno dei quali dipende solo dai gender1rispettivi gender2.

La risposta di Phil W. è probabilmente la risposta più flessibile in quanto consente un controllo esplicito sul saluto, anche se è del tutto corretto è un cambiamento radicale. Potresti non avere i dati in quel modulo.

La risposta di Kilian Foth è probabilmente la migliore per la domanda, sebbene dipenda dall'accendere una stringa, il che potrebbe non essere possibile o è probabilmente più costoso almeno.

Un perfezionamento della risposta di Kilian sta calcolando un singolo valore da entrambi gli input e attivando 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, poiché stai ricevendo tutti e quattro gli input (2 nomi e 2 sessi) da un database, aggiungere un'altra tabella e unirti a quello per ottenere il giusto saluto è probabilmente più flessibile e forse più facile di quanto sopra.


2

Se la tua lingua ti consente 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é esiste ancora la duplicazione, ma evita il nidificato switch.


5
Se lo fai, per amore dei cupcakes mettilo in un array o qualcosa del genere e sbarazzati del passaggio .... salutation ['MM'] = "Egregi Signori"; salutation ['MF'] = "Gentile signora e signore"; desideratoSalutazione = saluto [genere1 + genere2];
JDT,


Cosa chiamare dipende esattamente dalla lingua, ma fondamentalmente una raccolta di chiavi e valori, sì.
JDT,

1
C'è una leggera raffinatezza in ciò, che funziona in quasi tutte le lingue: calcola un singolo intero da entrambi i caratteri di input e accendilo, non su una stringa.
Deduplicatore,

0

In genere, si desidera che stringhe dell'interfaccia utente di questo tipo vengano estratte da una tabella di stringhe anziché essere codificate nel codice sorgente, per la localizzazione e la facilità di aggiornamento. Quindi l'approccio che seguirei sarebbe quello di utilizzare gli input per creare 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. Userei ancora una ricerca nella tabella delle stringhe nella soluzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.