【问题标题】:How to reduce if-condition looping - Swift如何减少 if 条件循环 - Swift
【发布时间】:2018-08-28 21:18:57
【问题描述】:

我知道这听起来很疯狂,但只是好奇如何减少 if 循环迭代以进行后续操作?我曾尝试使用guard let,但卡在某个地方。

{
        if arenaEventItems == nil || arenaEventItems.count <= 0 {
            return
        }
        if (arenaEventItems.count > 0 && (self.arenaEvents?.monthsDictObjList.count)! > 0){
            if (self.tableView != nil){
            if let arrVisibleRows = self.tableView.indexPathsForVisibleRows as? [IndexPath]{
                if (self.tableView.indexPathsForVisibleRows!.count > 0){
                    let indexPath : IndexPath =   self.tableView.indexPathsForVisibleRows!.first!
                    if let dict  = self.arenaEvents?.monthsDictObjList[indexPath.row] {
                        if(self.arenaHeaderView != nil) && (dict.count) > 0 {
                            self.arenaHeaderView?.setMonthTitle(string: (dict.keys.first!))
                            let selectedMonthTitle = (dict.keys.first!)

                            for month in  (self.arenaEvents?.uniqueMonthOnlyList)! {
                                if (selectedMonthTitle.contains(month)){
                                    selectedMonthIndex = (self.arenaEvents?.uniqueMonthOnlyList.index(of: month)!)!
                                    break
                                }
                            }
                        }
                    }
                }
            }
         }
       }
    }

【问题讨论】:

  • 您没有遵循 Swift 语言指南。将niloptional-binding 混合多次检查。不必要的注释类型IndexPath。嵌套的if 条件可以组合使用。还有更多...
  • @PriyankaMistry 不要忘记为有帮助的答案投票,并用绿色复选标记接受最有帮助的答案。 :)

标签: swift performance loops if-statement reduce


【解决方案1】:

您可以这样减少它,而无需任何强制展开或嵌套:

guard let arenaEventItems = arenaEventItems,
    !arenaEventItems.isEmpty,
    let arenaEvents = self.arenaEvents,
    !arenaEvents.monthsDictObjList.isEmpty,
    let arenaHeaderView = self.arenaHeaderView,
    let indexPath = self.tableView?.indexPathsForVisibleRows?.first,
    let selectedMonthTitle = arenaEvents.monthsDictObjList[indexPath.row].keys.first
    else {
        return
}
arenaHeaderView.setMonthTitle(string: selectedMonthTitle)
if let monthIndex = arenaEvents.uniqueMonthOnlyList.index(where: { selectedMonthTitle.contains($0) }) {
    selectedMonthIndex = monthIndex
}
  • 您将if ... return 替换为guard !... else return 以避免嵌套
  • 最好将 .count &gt; 0 替换为 !...isEmpty
  • 您将多个访问 self.something? 替换为 if let something = self.something 以避免线程问题
  • 你解开for ... in ... { if (...) { ... } }.index(where: ...)

【讨论】:

  • 感谢您提出最佳实践建议。也将尝试此代码。 :)
【解决方案2】:

您应该考虑重构您的代码,您的代码对于任何查看它的人来说都是不可读且难以理解的。由于您使用的是 Swift,因此使用 guard ... elseif ... let 编写这样的代码真的很容易 模式。

您可以在课堂上做的一些改进是让您的视图非零,即使它们隐式展开可选,因为您将始终将它们连接到情节提要。

 @IBOutlet var tableView: UITableView!
 @IBOutlet var arenaHeaderView: ArenaHeaderView!

另外,你有可以归零的数组,你为什么希望它归零。您可以简单地初始化一个空数组和字典。这样你就可以像这样减少一些比较代码,

arenaEventItems: [String: String] = [:]

通过这些更改和一些重构,您可能会将代码重写为类似的内容,

guard !arenaEventItems.isEmpty,
    let arenaEvents = arenaEvents,
    let indexPath = tableView.indexPathsForVisibleRows?.first,
    let dict = arenaEvents.monthsDictObjList[indexPath.row],
    let selectedMonthTitle = dict.keys.first

    else {
        return
}

arenaHeaderView.setMonthTitle(string: selectedMonthTitle)

for month in arenaEvents.uniqueMonthOnlyList where selectedMonthTitle.contains(month) {
    if let selectedIndex = arenaEvents.uniqueMonthOnlyList.index(of: month) {
        selectedMonthIndex = selectedIndex
        break
    }
}

【讨论】:

  • 感谢您提供简短的详细信息。将尝试在此处实施和更新。
【解决方案3】:

你可以将“if”中的所有条件组合起来,得到这样的结果:

if let eventItems = arenaEventItems,
   eventItems.count > 0,
   let events = self.arenaEvents,
   !events.monthsDictObjList.isEmpty,
   let tableView = self.tableView,
   let arrVisibleRows = self.tableView.indexPathsForVisibleRows as? [IndexPath],
   !arrVisibleRows.isEmpty,
   let indexPath : IndexPath = arrVisibleRows.first,
   let dict = events.monthsDictObjList[indexPath.row],
   let headerView = self.arenaHeaderView,
   !dict.isEmpty {
        headerView.setMonthTitle(string: (dict.keys.first!))
        let selectedMonthTitle = (dict.keys.first!)

        for month in events.uniqueMonthOnlyList! {
            if (selectedMonthTitle.contains(month)){
                selectedMonthIndex = (events.uniqueMonthOnlyList.index(of: month)!)!
                break
            }
        }
    }

【讨论】:

  • for ... in ... { if (...) { ... } } 构造可以简化为for ... in ... where ... { ... },如for month in events.uniqueMonthOnlyList! where selectedMonthTitle.contains(month) { selectedMonthIndex = ... } 。而直接的break 可以进一步简化为events.uniqueMonthOnlyList!.first(where: { ... })?...
  • 这正是您应该使用guard let 的情况。长的if 不可读。
猜你喜欢
  • 1970-01-01
  • 2016-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
  • 2022-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多