scala> List(List(1), List(2), List(3), List(4))
res18: List[List[Int]] = List(List(1), List(2), List(3), List(4))
scala> res18.flatten
res19: List[Int] = List(1, 2, 3, 4)
scala> res18.flatMap(identity)
res20: List[Int] = List(1, 2, 3, 4)
这两个功能有什么区别吗?何时使用一个而不是另一个?有任何权衡吗?
您可以将flatMap(identity)
视为map(identity).flatten
。 (当然它没有这样实现,因为它需要两次迭代)。
map(identity)
为您提供相同的集合,所以最后它只与flatten
相同。
我个人会坚持使用flatten
,因为它更短/更容易理解和设计来完全做到这一点。
从概念上讲,结果没有区别......
flatMap
花费更多的时间来产生相同的结果......
flatMap
, map
& then flatten
and flatten
object Test extends App { // flatmap println(timeElapsed(List(List(1, 2, 3, 4), List(5, 6, 7, 8)).flatMap(identity))) // map and then flatten println(timeElapsed(List(List(1, 2, 3, 4), List(5, 6, 7, 8)).map(identity).flatten)) // flatten println(timeElapsed(List(List(1, 2, 3, 4), List(5, 6, 7, 8)).flatten)) /** * timeElapsed */ def timeElapsed[T](block: => T): T = { val start = System.nanoTime() val res = block val totalTime = System.nanoTime - start println("Elapsed time: %1d nano seconds".format(totalTime)) res } }
flatMap
和flatten
在重复几次后执行相同的结果
flatten
is efficientElapsed time: 2915949 nano seconds List(1, 2, 3, 4, 5, 6, 7, 8) Elapsed time: 1060826 nano seconds List(1, 2, 3, 4, 5, 6, 7, 8) Elapsed time: 81172 nano seconds List(1, 2, 3, 4, 5, 6, 7, 8)
从概念上讲,没有区别。实际上,flatten
更有效率,并传达了更清晰的意图。
通常,您不直接使用identity
。它更像是作为参数传入或被设置为默认值的情况。编译器可以对其进行优化,但是你冒着对每个元素进行多余函数调用的风险。
当你需要做一个flatMap
(除了map
以外的函数)后立即使用identity
,你会使用flatten
。