将unzip 与函数一起使用
在 Scala 中,unzip 操作将函数作为隐式参数来生成该对,因此您可以一次性完成 map 和 unzip。这是 Scala 2.13.4 docs 中 List 的样子:
def unzip[A1, A2](implicit asPair: (A) => (A1, A2)): (List[A1], List[A2])
通过传递您自己的asPair 函数,您可以完成您正在寻找的结果:
scala> val l = List((8, 3, 9), (10, 3, 0), (-37, 4, 1))
val l: List[(Int, Int, Int)] = List((8,3,9), (10,3,0), (-37,4,1))
scala> val (list1, list2) = l.unzip(el => (el._1, el._2))
val list1: List[Int] = List(8, 10, -37)
val list2: List[Int] = List(3, 3, 4)
算法复杂度
unzip 函数的源代码位于文件 Iterable.scala 中的 trait scala.collection.IterableOps 中:
def unzip[A1, A2](implicit asPair: A => (A1, A2)): (CC[A1], CC[A2]) = {
val first: View[A1] = new View.Map[A, A1](this, asPair(_)._1)
val second: View[A2] = new View.Map[A, A2](this, asPair(_)._2)
(iterableFactory.from(first), iterableFactory.from(second))
}
如果我没看错的话,这个列表实际上被遍历了两次:每个列表生成一次。
但是,在您的原始解决方案中,列表被遍历了 3 次:一次用于 map 操作,两次用于 unzip 操作,所以我的解决方案仍然是一个改进。
@jwvh 建议的使用foldRight 的解决方案似乎只遍历列表一次,但foldRight 具有最初反转列表的开销(以便从列表的头部获取)。所以我想我的解决方案具有完全相同的算法复杂性。 (如果我错了,请纠正我。)