switchステートメントでswitchを減らす方法は?


9

データベースから2人に基づいて挨拶文を作成する方法を作成しています。

4つのパラメーターがあります。2つの名前(name1およびname2)および2つの性別(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'forのように複数の性別のオプションがあり、"Dear Relation"翻訳する時間のないいくつかのオプションがあることに注意してください。

この二重のswitchステートメントを減らすにはどうすればよいですか?

メソッドに2番目のスイッチを配置することはオプションではありません。両方の名前が同じで、出力を次のように組み合わせる必要がある場合もあります。 "Dear Sir and Madame name1,"



1
言語で許可されている場合は、両方の値によって変化する式をオンにしますgender1+gender2
Kilian Foth、2015

3
無関係な点で、ここで使用する女性のタイトルはMadam、ではなくMadameです。 Madameフランス語の形式です。
rojomoke 2015

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
それは時々動作しますが、時々動作しません...
Deduplicator

4
@Deduplicatorデフォルトでそれを行い、例外的なケースを個別に処理します。
Val

17
…それを関数にしgenderToTitleて、繰り返す必要がないようにしますか?(またはループを使用してください)
Bergi 2015

18

根本的な解決策:ユーザーが自分でタイトルを指定できるようにします(指定した定義済みリストから)。

あなたの解決策(英語の目で見た場合)は、領主(「サー」)と女性にのみ対応しているように見えます。ほとんどの男性は「夫人」、ほとんどの女性は「夫婦」、「夫人」または「夫婦」として扱われ、婚姻状況や個人的な意見に応じて異なります。それから、専門的な地位に基づく他の敬語がたくさんあります-「医師」、「教授」、「牧師」、そしてあなたのサイトについて本当に楽観的であると感じているなら、「神聖さ」!

より簡単な解決策:「性別」を敬語に変換するには、[単一の]関数が必要です。コードを1回記述して、両方の人に呼び出します。

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

ここでの問題は次のとおりです。私はデータベースをまったく制御できません。しかし、追加情報をありがとう、感謝します:)
moffeltje

8
Dear Sir住所の形がすべての男性にとって完全に受け入れられるので。タイトルとして、サー(のようにSir Phill)は(領主ではなく)騎士に制限されるべきであることに同意しますが、それは別の問題です。
rojomoke 2015

1
これがデータベースへのアクセスを必要とする方法はわかりません。これは、私にとって、これを行う最もクリーンな方法です。他にも素敵なスイッチの削減がありますが、これは最もクリーンな置き換えであり、ロジックをうまくモジュレートします。
Dan

4
@rojomokeいいえ、それは別の問題ではありません。この質問は「Dear Sir(ここに名前を挿入)」についてのものであり、単純な「Dear Sir」についてではありません。「Dear Sir(ここに名前を挿入)」タイトルとして「Sir」を使用しています。
hvd 2015

2003年頃のBAのマイレージフライヤーサインアップページには、タイトルのドロップダウンリストに「彼の神聖さ」がありました。それでも私が知っているすべてのことを行います。ドロップダウンが長すぎるため、統合しているポータブルブラウザがクラッシュしたことを覚えています。特にBAがデブレットに相談し、さまざまなコンテキスト(最低でも封筒のアドレスと挨拶文は異なる)について各タイトルの複数の形式を知っている場合を除いて、自由項目をお勧めします
Steve Jessop

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;

これの利点は、コード構造ではなくデータ構造に選択ロジックを埋め込むことです。これはデータベースへの委任に似ており、より柔軟です。あなたは、静的定数のどこかのようにそのマップを続ける場合は、次のことができ、ほとんどのデータベースのようにそれを使用します。それはしなくても、コードの多くの場所で使用することができ、更新に単一の構造になっ書くより多くのコードを。


3
関連資料

C ++の構文初期化子11で行くには良いアイデア、そしてそれを作るかもしれませんstatic conststatic const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};。まあ、const変更を許可する必要がある場合は省略できます。
デデュプリケータ2015

@Deduplicator間違いなく、もっと良い方法があります。言語タグがないので、ここでは単純化しようとしていました、C ++のように見えます。しかし、あなたは正しいです。C++ 11を想定しています。

3

文がすべて同じパターンであるが、2つのインセットがあり、gender1それぞれがそれぞれに依存している場合、ラチェットフリークの答えは非常に良い考えですgender2

Phil W.の回答は、挨拶を明示的に制御できるため、おそらく最も柔軟な回答です。その形式のデータがない可能性があります。

キリアン・フォスの答えはおそらく質問に最も適していますが、彼はストリングをオンにすることに依存しています。

キリアンの答えの改良点は、両方の入力から単一の値を計算し、それをオンにすることです。

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

もちろん、データベースから4つの入力(2つの名前と2つの性別)をすべて取得しているので、別のテーブルを追加し、それに結合して適切な挨拶を取得すると、おそらく上記よりも柔軟で簡単です。


2

あなたの言語がそれを可能にするなら、あなたは書くことができます

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

それは必ずしもありませんより良い重複がまだなので、お使いのバージョンよりも、それは、ネストされたを避けるんswitch


5
これを行う場合、カップケーキが大好きなため、これを配列または何かに入れて、スイッチを取り除きます。...salutation ['MM'] = "Dear Sirs"; salutation ['MF'] = "親愛なるマダムとサー"; desiredSalutation = salutation [gender1 + gender2];
JDT 2015

1
@JDT 辞書
gnat 2015

何と呼ぶか​​は言語によって異なりますが、基本的にはキーと値のコレクションです。
JDT 2015

1
これにはわずかな改良が加えられており、ほぼすべての言語で機能します。両方の入力文字から単一の整数を計算し、文字列ではなくそれをオンにします。
デデュプリケータ2015

0

ローカライズと更新を容易にするために、通常、このようなUI文字列は、ソースコードにハードコード化されているのではなく、文字列テーブルから取得する必要があります。したがって、私が取るアプローチは、入力を使用してルックアップキーを作成することです。

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

ユーザーが自分のタイトルを選択できるようにするための他の提案は、その情報を入手する機会があれば有効です。ソリューションでは引き続き文字列テーブルルックアップを使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.