过滤及;在Swift字典上画地图?

过滤及;在Swift字典上画地图?,swift,swift3,Swift,Swift3,我有两种方法做同样的事情,一种是使用功能更强大的Swift func getConstraints1(forState newState: State) -> (on: [NSLayoutConstraint], off: [NSLayoutConstraint]) { return ( constraints.filter { $0.key.rawValue == newState.rawValue }.map { $1 }.first!, const

我有两种方法做同样的事情,一种是使用功能更强大的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
中的语法。有没有在字典上执行过滤/映射/减少操作的案例?是这样吗?

每次你说
filter
map
,你都是在整个序列中循环。因此
getConstraints1
至少循环两次(可能是四次,但可能不是,因为考虑到惰性),而
getConstraints2
循环一次

问题是:你在乎吗?只有你(和仪器)能回答这个问题


就我个人而言,如果我要把一副牌分成两堆(比如说,所有的红牌和所有的黑牌),我会在这副牌上努力一次。把所有的红牌都放在一堆之后,我会觉得很傻,我会再次在牌堆中工作,看看剩下的每一张牌是否都是黑色的。

如果你的数据集太大,以至于对它进行两次迭代比使用function2更重要。通常,我认为这并不重要,因为它仍然会在O(n)中运行。如果需要函数方法,如果担心第二次迭代,可以修改filter函数以返回元组中的两个数组

这实际上取决于您映射/过滤/缩减的内容,因为每次调用一个项时,它都会迭代每个项。有时,使用map/filter/reduce比使用更大的for循环更具可读性

为了使
getConstraints2
更具功能性,您可以在这里使用reduce,它只会在字典上迭代一次。我对类型做了一些猜测,希望这与:)


什么类型的
约束
,有助于回答这个问题。据我所知,这两种方法的作用不同–第一种方法返回满足给定条件的第一对值(类型为
[NSLayoutConstraint]
),第二种方法将满足给定条件的所有值连接到两个数组中,并返回该对。哪个是正确的?@Hamish是的,我也在想这个问题。谢谢你提供了有趣的第三种方法:)
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
    }
}