Como reduzir uma opção em uma instrução de opção?

9

Então, eu estou criando um método para criar uma linha de saudação com base em duas pessoas de um banco de dados.

Existem quatro parâmetros: os dois nomes ( name1e name2) e os dois sexos ( gendere gender2).

Para cada combinação de gênero, tenho um tipo de saída diferente.

Por exemplo: se o gênero 1 for M(homem) e o gênero 2 também M, a saída deve ser algo como:

Dear Sir name1 and Sir name2,

No momento, meu switch fica assim:

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

Observe que tenho várias opções de gênero, como 'R'por "Dear Relation"e mais algumas que não tenho tempo para traduzir.

Como posso reduzir essa declaração de chave dupla?

Colocar a segunda opção em um método não é uma opção, porque também existe um caso em que os dois nomes são iguais e, em seguida, a saída deve ser combinada como: "Dear Sir and Madame name1,"

moffeltje
fonte
11
Se o seu idioma permitir, ative uma expressão que varia com os dois valores, por exemplo gender1+gender2.
Kilian Foth
3
Em um ponto não relacionado, o título feminino a ser usado aqui é Madam, não Madame. Madameé a forma francesa.
Rojomoke 14/07
3
Ligeiramente desnecessário, mas o fato de que a variável 'sexo' pode ser 'macho', ou 'relação' 'feminino' é um pouco perturbador ...
Paddy
4
"Note que eu tenho várias opções de gênero" Bem, isso certamente está em voga nos dias de hoje ...
Lightness Races in Orbit

Respostas:

32

Adicione o título aos parâmetros do 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);

você pode extrair a opção para sua própria função para reutilização e compactação.

catraca arrepiante
fonte
11
Isso às vezes funciona, às vezes não ...
Deduplicator
4
@Duplicador Faça isso por padrão e lide com casos excepcionais separadamente.
Val
17
… E transformar isso em uma função genderToTitlepara que você não precise repeti-la? (Ou use um loop)
Bergi
18

Solução radical: deixe o usuário especificar seu próprio título (em uma lista predefinida que você fornece).

Sua solução (como vista através dos olhos ingleses) parece servir apenas para Lordes ("Senhor") e senhoras; a maioria dos homens seria chamada de "senhor", a maioria das mulheres como "senhorita", "sra" ou "sra", dependendo do estado civil e das opiniões pessoais. Depois, há uma série de outros honoríficos baseados em classificações profissionais - "Médicos", "Professores", "Reverendos" e até mesmo, se você estiver realmente otimista com seu site, "Santidade"!

Solução mais simples: você precisa de uma função [única] para traduzir "gênero" em um honorífico. Codifique-o uma vez e chame-o para as duas pessoas:

printf("Dear %s %s and %s %s" 
   , getTitle( gender1 ), name1 
   , getTitle( gender2 ), name2 
   ) ; 
Phill W.
fonte
O problema aqui é: eu não tenho nenhum controle sobre o banco de dados. mas obrigado pela sua informação adicional, apreciá-lo :)
moffeltje
8
Dear Sircomo forma de endereço é perfeitamente aceitável para todos os homens. Concordo que, como título , Sir (como em Sir Phill) deve ser restrito a cavaleiros (não senhores), mas isso é uma questão diferente.
Rjomoke 14/07
11
Não vejo como isso exigiria acesso ao banco de dados. Este, para mim, é o método mais limpo de fazer isso. Existem outras reduções de switch agradáveis, mas essa é a substituição mais limpa, além de modular a lógica.
Dan
4
@rojomoke Não, isso não é uma questão diferente. Esta pergunta é sobre "Prezado Senhor (insira o nome aqui)", não sobre um simples "Prezado Senhor". "Prezado senhor (insira o nome aqui)" está usando "senhor" como título.
hvd 14/07
A página de inscrição de passageiro frequente da BA, talvez por volta de 2003, tinha "sua santidade" na lista suspensa de títulos. Ainda faz tudo o que sei. Lembro-me porque o menu suspenso foi tão longo que travou o navegador portátil que estávamos integrando. Eu recomendo um campo livre, a não ser que a BA em particular provavelmente consulta Debrett e conhece várias formas de cada título para diferentes contextos (endereço envelope diferente e saudação no mínimo)
Steve Jessop
9

Os títulos realmente pertencem ao banco de dados, mas você declarou que não tem controle sobre isso. Você não especificou uma marca de idioma, mas a sintaxe está na família C, portanto, será um pseudocódigo que é quase C ++:

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

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

O benefício disso é que você enterra a lógica de seleção em uma estrutura de dados em vez de em uma estrutura de código: é semelhante à delegação ao banco de dados e é mais flexível. Se você mantiver esse mapa como uma constante estática em algum lugar, quase poderá usá-lo como um banco de dados: ele se torna uma estrutura única para atualizar, que pode ser usada em muitos lugares do código sem precisar escrever mais código.


fonte
Pode ser uma boa idéia para ir com C ++ 11 initializer sintaxe e tornando-se static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. Bem, pode-se deixar de constfora se a modificação for permitida.
Deduplicator
@Duplicador definitivamente, existe uma maneira melhor. Eu estava indo para a simplicidade aqui, dado que não há marca de linguagem, mas parece C ++. Mas você está correto, assumindo C ++ 11.
3

A resposta da catraca é uma boa idéia se as frases tiverem o mesmo padrão, mas com duas inserções, uma dependente apenas da gender1respectiva gender2.

A resposta de Phil W. é provavelmente a resposta mais flexível, pois permite controle explícito sobre a saudação, embora ele esteja certo, é uma mudança radical. Você pode não ter os dados nesse formulário.

A resposta de Kilian Foth é provavelmente a melhor para a pergunta, embora ele dependa de ativar uma string, o que pode não ser possível ou provavelmente é mais caro, pelo menos.

Um refinamento na resposta de Kilian é calcular um valor único de ambas as entradas e ativar isso:

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

Obviamente, como você está obtendo todas as quatro entradas (2 nomes e 2 gêneros) de um banco de dados, adicionar outra tabela e se juntar a ela para obter a saudação adequada é provavelmente mais flexível e talvez mais fácil do que o descrito acima.

Desduplicador
fonte
2

Se o seu idioma permitir, você pode escrever

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

Não é necessariamente melhor que a sua versão, pois ainda existe duplicação, mas evita o aninhado switch.

Kilian Foth
fonte
5
Se você fizer isso, pelo amor de cupcakes, coloque-o em uma matriz ou algo assim e se livre do interruptor .... saudação ['MM'] = "Prezados Senhores"; saudação ['MF'] = "Prezada senhora e senhor"; Salutação desejada = saudação [sexo1 + sexo2];
JDT
11
@JDT dictionary ?
Gnat
O que chamar de isso depende exatamente do idioma, mas basicamente uma coleção de chaves e valores, sim.
JDT
11
Há um leve refinamento nisso, que funciona em praticamente qualquer idioma: calcule um único número inteiro de ambos os caracteres de entrada e ative isso, não em uma string.
Deduplicator
0

Você normalmente deseja que cadeias de UI como essa sejam extraídas de uma tabela de cadeias, em vez de serem codificadas no código-fonte, para localização e facilidade de atualização. Portanto, a abordagem que eu adotaria seria usar as entradas para criar uma chave de pesquisa, algo como:

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

As outras sugestões sobre permitir que os usuários selecionem seus próprios títulos são válidas, se você tiver a oportunidade de obter essas informações. Eu ainda usaria uma pesquisa de tabela de string na solução.

bmm6o
fonte