Як зменшити перемикач у операторі комутатора?


9

Тож я створюю метод створення лінії вітання для базування двох людей із бази даних.

Існує чотири параметри: два імені ( name1і name2) та два статі ( genderі gender2).

Для кожної гендерної комбінації у мене є різний результат.

Наприклад: якщо гендер 1 є M(чоловік), а також гендер 2 M, результат повинен бути таким, як:

Dear Sir name1 and Sir name2,

Наразі мій перемикач виглядає приблизно так:

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

Зверніть увагу , що у мене є кілька варіантів гендерних, як 'R'для "Dear Relation"і деякі більш , що у мене немає часу , щоб перевести.

Як я можу зменшити цю операцію подвійного перемикання?

Поставити другий перемикач методом не є варіантом, тому що також є випадок, коли обидва імена однакові, і тоді вихід слід поєднувати так: "Dear Sir and Madame name1,"



1
Якщо ваша мова дозволяє це, увімкніть вираз, який залежить від обох значень, наприклад gender1+gender2.
Кіліан Фот

3
Що стосується неспорідненого пункту, жіночий титул тут використовувати Madam, а не Madame. Madame- французька форма.
rojomoke

3
Трохи непотрібне, але той факт, що ваша змінна "стать" може бути "чоловічим", "жіночим" або "відношенням", трохи заважає ...
Paddy

4
"Зауважте, що у мене є декілька гендерних варіантів" Ну, це, безумовно, у моді сьогодні ...
Гонки легкості на Орбіті

Відповіді:


32

Додайте заголовок до параметрів 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);

ви можете витягнути перемикач на власну функцію для повторного використання та компактності.


1
Це іноді спрацьовує, інколи не ...
Дедуплікатор

4
@Deduplicator Зробіть це за замовчуванням та обробляйте виняткові випадки окремо.
Val

17
… І зробити цю функцію genderToTitleтак, що вам не доведеться її повторювати? (Або скористайтеся петлею)
Бергі

18

Радикальне рішення: Дайте користувачеві вказати власну назву (із заздалегідь визначеного списку, який ви надаєте).

Ваше рішення (як дивляться англійськими очима), здається, задовольняє лише лордів ("сер") та дам; більшість чоловіків вважатимуться "містером", більшість жінок - як "міс", "пані" або "пані", залежно від їх сімейного стану та особистої думки. Тоді виникла ціла низка інших почесних діянь, заснованих на професійних рейтингах - "Лікарі", "Професори", "Преподобні" і навіть, якщо ви відчуваєте справжній оптимізм щодо свого сайту, "Святість"!

Більш просте рішення: Вам потрібна функція [одиночний], щоб перевести "гендер" на загальнодоступний. Зашифруйте його один раз і назвіть його обом людям:

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

Проблема тут полягає в тому, що я не маю ніякого контролю над базою даних. але дякую за вашу додаткову інформацію, оцініть це :)
moffeltje

8
Dear Sirяк форма звернення цілком прийнятна для всіх чоловіків. Я погоджуюсь, що як титул , сер (як в Sir Phill) повинен бути обмежений лицарями (а не лордами), але це інша справа.
rojomoke

1
Я не бачу, як це вимагатиме доступу до бази даних. Це, на мій погляд, найчистіший метод цього зробити. Є й інші приємні скорочення перемикачів, але це найчистіша заміна, а також чудово модулююча логіка.
Dan

4
@rojomoke Ні, це не інша справа. Це питання стосується "Шановний пане (введіть тут ім'я)", а не про простий "Шановний пане". «Шановний (вставити ім'я тут)» в використанні «сер» в якості назви.
hvd

Сторінка реєстрації листів BA, яка часто використовує листівки, можливо, приблизно в 2003 році, мала "свою святість" у випадаючому списку назв. Досі робить для всіх, що я знаю. Я пам’ятаю, оскільки спадне меню було настільки довгим, що воно розбило портативний браузер, який ми інтегрували. Я рекомендую вільне поле, за винятком того, що BA, зокрема, ймовірно, консультується з Дебретом і знає кілька форм кожного заголовка для різних контекстів (різні адреси конвертів та привітання як мінімум)
Стів Джессоп

9

Заголовки дійсно належать до бази даних, але ви заявили, що не маєте контролю над цим. Ви не вказали мовний тег, але синтаксис є у сімействі C, тож це буде псевдокод, що майже C ++:

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

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

Користь для цього полягає в тому, що ви закопуєте логіку вибору в структуру даних, а не структуру коду: це схоже на делегування в базу даних і є більш гнучким. Якщо ви зберігаєте цю карту як статичну константу десь, ви майже можете використовувати її як базу даних: вона стає єдиною структурою для оновлення, яку можна використовувати в багатьох місцях у коді, не потрібно писати більше коду.



Це може бути гарною ідеєю , щоб піти з C ++ 11 ініціалізатор синтаксис і робить його static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. Що ж, можна вийти з нього const, якщо його дозволити.
Дедуплікатор

@Deduplicator напевно, є кращий спосіб. Я збирався для простоти тут даній немає мови тегів , але це виглядає як C ++. Але ви праві, припускаючи C ++ 11.

3

Відповідь щурячого виродка є досить хорошою ідеєю, якщо речення мають однаковий зразок, але з двома вписами, кожне з яких залежить лише від gender1відповідних gender2.

Відповідь Філа У. - це, мабуть, найбільш гнучка відповідь, оскільки він дозволяє чітко контролювати привітання, хоча він цілком правильний - це радикальна зміна. Ви можете не мати даних у цій формі.

Відповідь Кіліана Фота, мабуть, найкраща на запитання, яке йому задають, хоча він залежить від перемикання на рядок, що може бути неможливим або, мабуть, принаймні дорожчим.

Уточнення відповіді Кіліана обчислює єдине значення з обох входів та перемикання на це:

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

Звичайно, оскільки ви отримуєте всі чотири входи (2 імені та 2 статі) з бази даних, додавання ще однієї таблиці та приєднання до цього, щоб отримати належне вітання, напевно, є більш гнучким і, можливо, простіше, ніж вище.


2

Якщо ваша мова дозволяє це робити, ви можете писати

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

Це не обов’язково краще, ніж ваша версія, оскільки все ще є дублювання, але це уникає вкладених switch.


5
Якщо ви це зробите, для любові кекси покладіть це в масив чи щось і позбудьтесь перемикача .... привітання ['MM'] = "Шановні панове"; привітання ['MF'] = "Шановна пані та сер"; бажана салютація = привітання [гендер1 + стать2];
JDT


Що саме називати, залежить від мови, але в основному це набір ключів і значень, так.
JDT

1
Існує невелике уточнення до цього, яке працює практично на будь-якій мові: обчисліть одне ціле число з обох вхідних символів, і увімкніть це, а не на рядок.
Дедуплікатор

0

Зазвичай ви хочете, щоб такі рядки інтерфейсу користувача витягувалися з таблиці рядків, а не були жорстко закодовані у вихідному коді, для локалізації та зручності оновлення. Таким чином, я підходив би до використання вхідних даних для побудови ключа пошуку, щоб щось подібне:

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

Інші пропозиції щодо дозволу користувачам вибирати власні заголовки є дійсними, якщо у вас є можливість отримати цю інформацію. Я б все-таки використовував пошук розв'язувальної таблиці в рішенні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.