【问题标题】:Swift: Reduce optional array of models to single Bool by optional propertySwift:通过可选属性将可选模型数组减少为单个 Bool
【发布时间】:2017-10-10 15:00:56
【问题描述】:

我刚刚在 swift 中了解了 map、flatMap 和 reduce 的美妙世界,我已经在任何有意义的地方使用它并帮助改进我的代码。

现在我遇到了一个非常特殊的问题,我想知道是否有使用 map、flatMap 和/或 reduce 的解决方案。

在我的模型类中,我有一个可选的其他模型数组。这些模型有一个可选的 Bool 属性。我现在想知道整个模型数组是否至少包含一个具有真实属性的模型。这就是我目前正在做的事情:

class ModelA{
  var bModels: [ModelB]?
}
class ModelB{
  var aBool: Bool?
}

func hasATrue(aModel: ModelA) {
    guard let bModels = aModel.bModels else { return false }
    for bModel in bModels {
        if bModel.aBool == true {
            return true
        }
    }
    return false
}

【问题讨论】:

  • 您正在寻找contains(where:) - 比较stackoverflow.com/q/29679486/2976878
  • 在你的情况下return aModel.bModels?.contains(where: { $0.aBool == true }) ?? false
  • return aModel.bModels?.contains(where: { $0.aBool == true }) == true – 更加对称:)
  • 你也可以使用reduce:return aModel.bModels?.reduce(false) { $0 || $1.aBool ?? false } == true
  • @paulvs:我不建议这样做。 reduce 不像 contains 那样短路。

标签: swift dictionary reduce flatmap


【解决方案1】:

您可以使用可选链接 Array.contains(where:) 和 nil 合并在单个表达式中完成所有操作。

func hasATrue(aModel: ModelA) {
    return aModel.bModels?.contains(where: { $0.aBool == true }) ?? false
}

【讨论】:

  • 那不会编译(因为aBool 是可选的)。
  • @MartinR 啊,我错过了。固定。
【解决方案2】:

根据我的问题中的 cmets,这就是解决问题的方法:

return aModel.bModels?.contains(where: { $0.aBool == true }) ?? false

或者

return aModel.bModels?.contains(where: { $0.aBool == true }) == true

一个比另一个更好吗?我不知道。也许对如何实现语言有深入了解的 Swift 专家可以判断哪个更快/更高效,但对我来说,这种方法很少被调用,因此处理时间不是问题,但这是另一个话题。

感谢所有评论者。我对 map、flatMap 和 reduce 非常着迷,以至于我没有看到明显的东西(我也不知道你可以在 swift 中将闭包传递给 contains 函数)。我一天天越来越喜欢这种语言。

每次我要为 Android 编写 Java 代码时,我都快哭了?

【讨论】:

  • 如果您的问题得到解答,请接受其中一个答案。
  • return aModel.bModels?.contains(where: { $0.aBool ?? false }) ?? false :)
  • @Alexander,您可以在答案中添加所有 3 个变体吗?然后我会接受你的并删除我自己的:)
  • @xxtesaxx 这些不是我的答案,我不会通过将它们放在我的答案中来窃取信用。如果他们有兴趣,他们各自的所有者可以发布它们。
  • 从性能的角度来看,$0.aBool == true 隐式地将rhs (true) 包装成一个可选的布尔值,然后== 的实现将左右两边都展开。编译器可能会优化掉其中的大部分内容,但引入的步骤远不止$0.aBool ?? false
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-07
  • 2018-12-31
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
相关资源
最近更新 更多