如何在switch语句中减少switch?


9

因此,我正在基于数据库中的两个人创建一种称呼行的方法。

有四个参数:两个名称(name1name2)和两个性别(gendergender2)。

对于每种性别组合,我都有不同的输出。

例如:如果性别1为M(man)且性别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
Kilian Foth,2015年

3
在不相关的一点上,此处使用的女性头衔Madam不是MadameMadame是法国形式。
rojomoke

3
稍微没有必要,但是您的“性别”变量可以是“男性”,“女性”或“关系”这一事实令人不安...
Paddy

4
“请注意,我有多种性别选择”嗯,这些天肯定很流行……
轨道轻轨比赛

Answers:


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默认情况下执行此操作,并分别处理特殊情况。
2015年

17
…并使其成为一个函数,genderToTitle这样您就不必重复它了?(或使用循环)
Bergi 2015年

18

激进的解决方案:让用户指定自己标题(从您提供的预定义列表中)。

您的解决方案(通过英语观看)只能满足上议院(“先生”)和女士们的需要;根据他们的婚姻状况和个人意见,大多数男人被称为“先生”,大多数女人被称为“小姐”,“太太”或“女士”。然后还有大量其他基于专业地位的荣誉–“医生”,“教授”,“牧师”,甚至,如果您对自己的网站感到非常乐观,那就是“圣洁”!

更简单的解决方案:您需要一个[单个]函数将“性别”转换为敬语。对其进行一次编码并为两个人调用:

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

这里的问题是:我对数据库没有任何控制。但感谢您的其他信息,不胜感激:)
moffeltje15年

8
Dear Sir因为所有男性都完全可以接受一种称呼形式。我同意,作为头衔,爵士(如中所述Sir Phill)应仅限于骑士(而非君主),但这是另一回事。
rojomoke

1
我看不出这将如何要求访问数据库。对我来说,这是最干净的方法。还有其他一些减少开关的方法,但这是最干净的替代方法,并且可以很好地调制逻辑。

4
@rojomoke不,那没什么不同。这个问题是关于“亲爱的先生(在此处插入名称)”,而不是关于一个简单的“亲爱的先生”。“亲爱的先生(此处插入名称)” 使用“先生”的称号。
hvd 2015年

可能在2003年左右,BA的飞行常客注册页面在标题的下拉列表中有“他的圣洁”。依我所知仍然如此。我记得,因为下拉菜单的时间太长,它使我们集成的便携式浏览器崩溃了。我建议您提供一个自由字段,除非BA特别会咨询Debrett's并知道每种标题的多种形式以用于不同的上下文(不同的信封地址和称呼语最少)
Steve Jessop 2015年

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 conststatic const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};。好吧,const如果可以修改的话,可以省去。
Deduplicator

@Deduplicator肯定有更好的方法。考虑到没有语言标签,我在这里只是为了简单起见,但它看起来像C ++。但是您假设C ++ 11是正确的。

3

如果句子都是相同的模式,但是有两个插图,每个插图仅取决于gender1各自的,则棘轮怪胎的答案是一个很好的主意gender2

菲尔·W(Phil W.)的答案可能是最灵活的答案,因为它可以明确控制问候语,尽管他说的很对,这是一个根本性的改变。您可能没有该格式的数据。

Kilian Foth的答案可能是所提出问题的最佳答案,尽管他依赖于接通字符串,但这可能是不可能的,或者至少可能更昂贵。

对Kilian答案的一种改进是从两个输入中计算一个值,然后将其打开:

// 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
如果您这样做,则出于对纸杯蛋糕的热爱,请将其放在阵列中或类似的东西上,并摆脱开关的问题。salutation ['MF'] =“亲爱的女士和先生”;requiredSalutation =称呼[性别1 +性别2];
JDT

1
@JDT 字典
蚊蚋

调用的内容完全取决于语言,但基本上是键和值的集合,是的。
JDT

1
有一点点改进,几乎可以在任何语言中使用:从两个输入字符中计算一个整数,然后打开它,而不是字符串。
Deduplicator 2015年

0

通常,您希望将这样的UI字符串从字符串表中拉入,而不是在源代码中进行硬编码,以实现本地化和易于更新。因此,我采用的方法是使用输入来构建查找键,如下所示:

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

如果您有机会获得有关该信息的其他建议,则可以让用户选择自己的标题。我仍将在解决方案中使用字符串表查找。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.