Comment réduire un commutateur dans une instruction switch?

9

Je fais donc une méthode pour créer une ligne de salutation basée sur deux personnes à partir d'une base de données.

Il y a quatre paramètres: les deux noms ( name1et name2) et les deux sexes ( genderet gender2).

Pour chaque combinaison de genre, j'ai une sorte de sortie différente.

Par exemple: si le genre 1 est M(homme) et le genre 2 l'est également M, le résultat devrait être quelque chose comme:

Dear Sir name1 and Sir name2,

À ce moment, mon interrupteur ressemble à ceci:

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

Notez que j'ai plusieurs options de genre, comme 'R'pour "Dear Relation"et plus que je n'ai pas le temps de traduire.

Comment puis-je réduire cette déclaration de double commutation?

Mettre le deuxième commutateur dans une méthode n'est pas une option car il y a aussi un cas où les deux noms sont identiques et la sortie doit être combinée comme: "Dear Sir and Madame name1,"

moffeltje
la source
1
Si votre langue le permet, activez une expression qui varie avec les deux valeurs, par exemple gender1+gender2.
Kilian Foth
3
Sur un point sans rapport, le titre féminin à utiliser ici ne l'est Madampas Madame. Madameest la forme française.
rojomoke
3
Un peu inutile, mais le fait que votre variable "genre" puisse être "masculin", "féminin" ou "relation" est un peu dérangeant ...
Paddy
4
"Notez que j'ai plusieurs options de genre" Eh bien, c'est certainement en vogue ces jours-ci ...
Courses de légèreté en orbite

Réponses:

32

Ajoutez le titre aux paramètres du 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);

vous pouvez extraire le commutateur à sa propre fonction pour la réutilisation et la compacité.

monstre à cliquet
la source
1
Cela fonctionne parfois, parfois non ...
Déduplicateur
4
@Deduplicator Faites cela par défaut et gérez les cas exceptionnels séparément.
Val
17
… Et en faire une fonction genderToTitlepour que vous n'ayez pas à la répéter? (Ou utilisez une boucle)
Bergi
18

Solution radicale: laissez l'utilisateur spécifier son propre titre (à partir d'une liste prédéfinie que vous fournissez).

Votre solution (vue à travers les yeux anglais) ne semble répondre qu'aux Lords ("Sir") et aux dames; la plupart des hommes seraient appelés "M.", la plupart des femmes "Miss", "Mrs" ou "Ms", selon leur état civil et leurs opinions personnelles. Ensuite, il y a toute une série d'autres titres honorifiques basés sur des classements professionnels - "Médecins", "Professeurs", "Révérends" et même, si vous vous sentez vraiment optimiste quant à votre site, "Sainteté"!

Solution plus simple: vous avez besoin d'une fonction [unique] pour traduire «genre» en un titre honorifique. Codez-le une fois et appelez-le pour les deux personnes:

printf("Dear %s %s and %s %s" 
   , getTitle( gender1 ), name1 
   , getTitle( gender2 ), name2 
   ) ; 
Phill W.
la source
Le problème est le suivant: je n'ai aucun contrôle sur la base de données. mais merci pour vos informations supplémentaires, appréciez-le :)
moffeltje
8
Dear Sircomme forme d'adresse est parfaitement acceptable pour tous les hommes. Je conviens qu'en tant que titre , Sir (comme dans Sir Phill) devrait être réservé aux chevaliers (pas aux seigneurs), mais c'est une autre affaire.
rojomoke
1
Je ne vois pas comment cela nécessiterait l'accès à la base de données. Pour moi, c'est la méthode la plus propre de le faire. Il existe d'autres réductions intéressantes de commutateur, mais c'est le remplacement le plus propre, ainsi que la modulation de la logique.
Dan
4
@rojomoke Non, ce n'est pas différent. Cette question concerne "Cher Monsieur (insérez le nom ici)", pas un simple "Cher Monsieur". « Cher Monsieur (insérer le nom ici) » est en utilisant « Monsieur » comme un titre.
hvd
La page d'inscription aux grands voyageurs de BA, peut-être vers 2003, avait "sa sainteté" dans la liste déroulante des titres. Fait toujours pour tout ce que je sais. Je me souviens parce que la liste déroulante était si longue qu'elle a fait planter le navigateur portable que nous intégrions. Je recommanderais un champ libre, sauf que BA en particulier consulte probablement Debrett et connaît plusieurs formes de chaque titre pour différents contextes (adresse d'enveloppe et salutation différentes au minimum)
Steve Jessop
9

Les titres appartiennent vraiment à la base de données, mais vous avez déclaré que vous n'aviez aucun contrôle sur cela. Vous n'avez pas spécifié de balise de langue mais la syntaxe est dans la famille C, donc ce sera un pseudocode qui est presque C ++:

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

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

L'avantage est que vous enterrez la logique de sélection dans une structure de données plutôt que dans une structure de code: cela est similaire à la délégation à la base de données et est plus flexible. Si vous conservez cette carte comme constante statique quelque part, vous pouvez presque l' utiliser comme une base de données: elle devient une structure unique à mettre à jour qui peut être utilisée à de nombreux endroits du code sans avoir besoin d' écrire plus de code.


la source
Il pourrait être une bonne idée d'aller avec C ++ 11 initialiseur syntaxe, et ce qui en fait static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. Eh bien, on peut laisser de constcôté si la modification doit être autorisée.
Deduplicator
@Deduplicator, il y a certainement une meilleure façon. J'allais pour la simplicité ici étant donné qu'il n'y a pas de balise de langue mais cela ressemble à C ++. Mais vous avez raison, en supposant que C ++ 11.
3

La réponse de Ratchet Freak est une bonne idée si les phrases sont toutes du même modèle, mais avec deux encarts, chacun dépendant uniquement de leur gender1respectif gender2.

La réponse de Phil W. est probablement la réponse la plus flexible car elle permet un contrôle explicite sur le message d'accueil, bien qu'il ait tout à fait raison, c'est un changement radical. Vous pourriez ne pas avoir les données sous cette forme.

La réponse de Kilian Foth est probablement la meilleure pour la question posée, bien qu'il dépende de l'activation d'une chaîne, ce qui pourrait ne pas être possible ou est probablement plus cher au moins.

Un raffinement de la réponse de Kilian consiste à calculer une valeur unique à partir des deux entrées et à activer cette fonction:

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

Bien sûr, comme vous obtenez les quatre entrées (2 noms et 2 genres) à partir d'une base de données, ajouter une autre table et vous y joindre pour obtenir la bonne salutation est probablement plus flexible et peut-être plus facile que ci-dessus.

Déduplicateur
la source
2

Si votre langue vous le permet, vous pouvez écrire

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

Ce n'est pas nécessairement mieux que votre version, car il y a toujours duplication, mais cela évite l'imbriqué switch.

Kilian Foth
la source
5
Si vous faites cela, pour l'amour des cupcakes, mettez cela dans un tableau ou quelque chose et débarrassez-vous de l'interrupteur .... salutation ['MM'] = "Chers Messieurs"; salutation ['MF'] = "Chère Madame et Monsieur"; desireSalutation = salutation [sexe1 + sexe2];
JDT
1
Dictionnaire @JDT ?
gnat
Comment appeler cela dépend exactement de la langue, mais essentiellement une collection de clés et de valeurs, oui.
JDT
1
Il y a un léger raffinement à cela, qui fonctionne dans à peu près n'importe quelle langue: calculez un seul entier à partir des deux caractères d'entrée, et activez-le, pas sur une chaîne.
Déduplicateur
0

Vous voudriez généralement que des chaînes d'interface utilisateur comme celle-ci soient extraites d'une table de chaînes au lieu d'être codées en dur dans le code source, pour la localisation et la facilité de mise à jour. Donc, l'approche que je prendrais serait d'utiliser les entrées pour construire une clé de recherche, donc quelque chose comme:

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

Les autres suggestions concernant la possibilité pour les utilisateurs de sélectionner leurs propres titres sont valables, si vous avez la possibilité d'obtenir ces informations. J'utiliserais toujours une recherche de table de chaînes dans la solution.

bmm6o
la source