过滤器&在Swift词典上映射?

时间:2016-09-12 18:10:51

标签: swift swift3

我有两种方法做同样的事情,一种使用功能更强大的Swift。

  func getConstraints1(forState newState: State) -> (on: [NSLayoutConstraint], off: [NSLayoutConstraint]) {
    return (
      constraints.filter { $0.key.rawValue == newState.rawValue }.map { $1 }.first!,
      constraints.filter { $0.key.rawValue != newState.rawValue }.map { $1 }.first!
    )
  }

另一个使用标准程序方法。

func getConstraints2(for nextState: State) -> (on: [NSLayoutConstraint], off: [NSLayoutConstraint]) {
    var on = [NSLayoutConstraint]()
    var off = [NSLayoutConstraint]()

    for (state, constraints) in constraints {
      if state == nextState {
        on += constraints
      } else {
        off += constraints
      }
    }

    return (on, off)
  }

我觉得getConstraints2会比getConstraints1更快,但我喜欢getConstraints1中的语法。有没有案例要对字典进行过滤/映射/减少操作?这是吗?

3 个答案:

答案 0 :(得分:2)

每当你说filtermap时,你就会在整个序列中循环。所以getConstraints1至少循环两次(可能是四次,但可能不是,因为懒惰考虑),而getConstraints2循环一次。

问题是:你关心吗?只有你(和乐器)可以回答那个。

就个人而言,如果我打算将一副扑克牌分成两堆(比如所有的红牌和所有黑牌),我会在牌组中进行一次。将所有的红牌分成一堆,我觉得自己在甲板上再次傻乎乎地看着每张剩下的牌是否是黑色。

答案 1 :(得分:2)

如果你的数据集太大,那么迭代它比使用function2要重要两倍。通常情况下,我认为这不重要,因为它仍然会在O(n)中运行。如果你想要一个功能方法,你可以一直修改你的过滤器函数,如果你担心第二次迭代,就会在一个元组中返回两个数组。

答案 2 :(得分:2)

这实际上取决于你是映射/过滤/减少什么,因为它会在每次调用一个项目时迭代每个项目。有时使用map / filter / reduce可以比循环更大的可读性。

为了使getConstraints2更具功能性,你可以在这里使用reduce,它只会迭代字典一次。我对这些类型进行了一些猜测,所以希望这匹配起来:)

typealias StatefulConstraints = (on: [NSLayoutConstraint], off: [NSLayoutConstraint])

var constraints = [State: [NSLayoutConstraint]]()

func getConstraints3(for nextSate: State) -> StatefulConstraints {
    let initial = (on: [NSLayoutConstraint](), off: [NSLayoutConstraint]())
    return constraints.reduce(initial) { (combined, next: (state: State, constraints: [NSLayoutConstraint])) -> StatefulConstraints in
        var mutableCombined = combined
        if next.state == nextSate {
            mutableCombined.on += next.constraints
        } else {
            mutableCombined.off += next.constraints
        }
        return mutableCombined
    }
}