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,"



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.


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

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.



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.


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.


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.