【问题标题】:More efficient way to write conditionals with lots of OR operators使用大量 OR 运算符编写条件的更有效方法
【发布时间】:2014-08-11 20:20:58
【问题描述】:

我如何(更)有效地写出使用相同变量和大量 OR 运算符的 if / else 条件?

我一直在努力想办法用相同的比较写出所有这些 OR 运算符。 For 循环不会成功,我很确定 do / while 循环也不会这样做。 switch / case 可能会解决这个问题,但我认为它不会压缩代码或减少写出的乏味。

下面的例子说明了我的困境。 API 有一个协议方法,该方法为集合中的每个部分调用,并且需要该部分中项目数的返回值。本质上,下面的协议方法是一个花哨的 for 循环。

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (section == 0 || section == 31) return 7;
    else if (section == 1 || section == 26 || section == 27 || section == 28 || section == 29 || section == 30) return 6;
    else if (section == 2 || section == 3 || section == 4 || section == 5 || section == 6 || section == 7 || section == 8 || section == 9 || section == 10 || section == 11 || section == 12 || section == 13 || section == 14 || section == 15) return 2;
    else if (section == 16 || section == 17 || section == 18 || section == 19 || section == 20 || section == 21 || section == 22 || section == 23 || section == 24 || section == 25) return 4;
    else return 7;
}

正如您在我编写的极其繁琐的 if / else 条件中所见,它会检查每个部分。我觉得我错过了一些东西——Objective-C 提供了一种很好的方法来解决这种乏味且低效的条件编写/检查?

【问题讨论】:

  • 您可以为这些映射使用字典。
  • 或者更好的是,不要使用静态值。有一个代表每个部分的数组。然后只需询问适当的数组它有多大。您共享的代码似乎是在尝试使用视图模型。不要抗拒,视图模型很棒。
  • 是的,拥有合适的数据结构可以解决这个问题。也就是说,您的几个条件表达式相当于检查一个值是否在整数范围内。您可以将它们折叠成2 <= section && section <= 1516 <= section && section <= 25 等。
  • ...或者只使用 NSIndexSex。这就是它的用途。
  • 使用<=>= @KenThomases 是对的,但这个问题也可以更广泛地应用(例如,字符串、字典等)。

标签: uicollectionview objective-c c cocoa-touch optimization conditional-statements


【解决方案1】:

一种简洁的方法是使用switch 语句。这些通常使用分支数组来实现,因此非常有效。

switch (section)
{
case 0:
case 31:
    return 7;
...
}

最有效的(无分支)是查找表:

const int nums[]= { 7, 6, 2, 2, 2... };

return nums[section];

【讨论】:

  • 我建议使用 switch。更干净、更清晰、更易于评论来描述你在做什么。使用位掩码和范围折叠可以隐藏意图并引入意外错误。
【解决方案2】:

switch 可能是正确的答案,但您也可以使用 shift/mask,例如:

int sectionBit = 0x00000001 << section;
if (sectionBit & 0x80000001) return 7;
if (sectionBit & 0x7c000002) return 6;
etc

这种方法的缺点是定义位常量很繁琐且容易出错,但有时可以通过使用枚举等来开发常量(以长声明字符串为代价)。

【讨论】:

    【解决方案3】:

    对此的通用方法是使用NSArray / NSDictionary 来构建索引,例如:

    NSArray *sections = @[@3, @5, @27, ...];
    if ([sections containsObject:@3]) ...
    

    NSDictionary *sections = @{ @5: @27, @7: @23, ... };
    int value = [sections[@(section)] intValue]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-19
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多