【问题标题】:How can I make the following code dry?如何使以下代码变干?
【发布时间】:2009-06-13 03:37:17
【问题描述】:

如何使我的以下代码“干燥”(不要重复自己)

- (void)updateLetterScore { // NOT DRY... Must fix
    if (percentScore < 60.0)
        letterLabel.text = [NSString stringWithFormat:@"F"];

    if (percentScore > 59.0 && percentScore < 64.0)
        letterLabel.text = [NSString stringWithFormat:@"D-"];

    if (percentScore > 64.0 &&  percentScore < 67.0)
        letterLabel.text = [NSString stringWithFormat:@"D"]; 

    if (percentScore > 66.0 &&  percentScore < 70.0)
        letterLabel.text = [NSString stringWithFormat:@"D+"]; 

    if (percentScore > 69.0 &&  percentScore < 74.0)
        letterLabel.text = [NSString stringWithFormat:@"C-"]; 

    if (percentScore > 73.0 &&  percentScore < 76.0)
        letterLabel.text = [NSString stringWithFormat:@"C"];

    if (percentScore > 76.0 &&  percentScore < 80.0)
        letterLabel.text = [NSString stringWithFormat:@"C+"];

    if (percentScore > 79.0 &&  percentScore < 84.0)
        letterLabel.text = [NSString stringWithFormat:@"B-"];

    if (percentScore > 83.0 &&  percentScore < 86.0)
        letterLabel.text = [NSString stringWithFormat:@"B"];

    if (percentScore > 85.0 &&  percentScore < 90.0)
        letterLabel.text = [NSString stringWithFormat:@"B+"];

    if (percentScore > 89.0 &&  percentScore < 94.0)
        letterLabel.text = [NSString stringWithFormat:@"A-"];

    if (percentScore > 93.0 &&  percentScore < 100.0)
        letterLabel.text = [NSString stringWithFormat:@"A"];

    if (percentScore == 100)
        letterLabel.text = [NSString stringWithFormat:@"A+"];
}

感谢您的提示。我只是想知道你们的想法,因为这个小片段在我的代码中看起来很可怕。

【问题讨论】:

  • 忽略主要问题,你为什么要使用 +stringWithFormat:?您的所有字符串都没有任何格式信息,所以直接分配字符串。例如letterLabel.text = @"A";

标签: objective-c cocoa dry


【解决方案1】:

一种方式(伪代码,因为我不知道目标 C):

grades = ["F", "D-", "D", ...]
scores = [60.0, 64.0, 67.0, ...]

for(i = 0; i < grades.count; i = i + 1)
{
   if(score < scores[i])
   {
     letterLabel.text = [NSString stringWithFormat:@"%@", grades[i]]
     break;
   }
}

【讨论】:

  • 您可以使用地图来代替两个数组。
  • 我也不知道目标 C——但在这种情况下,我倾向于将数据放入记录中,并且只有一个记录数组而不是两个值——没有办法不小心让它们在编辑时不同步。
  • 地图的问题是您需要一种方法来按顺序移动它们。我同意记录。这个想法掠过我的脑海,但我很简单。
  • 这个问题是每个年级都没有范围。而且它并不总是完美的数字,例如 60、64 或 67。那么解决方案是什么?
  • 这个表达式 [NSString stringWithFormat:grades[i]] 应该写成 [NSString stringWithFormat:@"%@", grades[i]] 如果一个等级被命名为 "% @",之前的代码会崩溃。确实,您不太可能做这么好的事情,养成从不将原始字符串作为格式字符串传递的习惯是件好事。另外,为什么不把 score 做成一个objective-c 字符串数组呢?然后你不需要在调用方法时分配一个,你只需要使用编译的常量字符串之一。
【解决方案2】:

和其他人一样,我会将值放入一个表中,然后扫描该表。该表很小,可能不值得像树一样制作一些更高效的 O() 结构。

typedef struct {
    float minPercent;
    NSString *letterGrade;
} GradeRange

- (NSString *)letterGradeForPercentage:(float)percentage {
    GradeRange ranges[] = {{.minPercent = 100, .letterGrade = @"A+"},
                           ...
                           {.minPercent = 66.0, .letterGrade = @"D+"},
                           {.minPercent = 64.0, .letterGrade = @"D"}};

    NSString *grade = nil;
    for(NSInteger i = 0; !grade && i < (sizeof(ranges) / sizeof(ranges[0])); i += 1) {
        if (percentage >= ranges[i].minPercent) {
            grade = ranges[i].letterGrade;
        }
    }
    return grade;
}

【讨论】:

    【解决方案3】:

    Talljoe 展示了一种方法,但想法只是将所有分数存储在某种查找表中

    【讨论】:

      【解决方案4】:

      如果这个可憎的事情由我负责,我会提取所有的魔法值并将它们放在一个表格中,然后遍历表格检查您的 percentScore 属于哪个范围。您可能需要重新检查所有范围,但它们不会'似乎没有解决 percentScore 可以假设的所有值。

      【讨论】:

        【解决方案5】:

        这里涉及到所有一百个条目,使用包含等级字母代码和 [array objectAtIndex: i] 基于整数等级值的数组偏移量的数组。完成。

        使用 Cocoa,您可以直接在代码中构建此数组,也可以从后备存储 (arrayWithContentsOfFile:) 加载数组并让 Cocoa 整理存储。

        您可以通过允许用户通过重写保存的成绩数组来调整成绩范围来对这种特殊设计进行加分,并且代码本身不会改变。

        【讨论】:

          猜你喜欢
          • 2011-06-22
          • 2020-07-27
          • 1970-01-01
          • 2014-12-13
          • 1970-01-01
          • 1970-01-01
          • 2011-05-25
          • 1970-01-01
          相关资源
          最近更新 更多