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)
这两个功能有什么区别吗?何时使用一个而不是另一个?有任何权衡吗?
答案 0 :(得分:9)
您可以将flatMap(identity)
视为map(identity).flatten
。 (当然它没有这样实现,因为它需要两次迭代)。
map(identity)
为您提供相同的集合,因此最终只与flatten
相同。
我个人会坚持flatten
,因为它更短/更容易理解和设计来完全做到这一点。
答案 1 :(得分:5)
从概念上讲,结果没有差异......
flatMap
正在采取行动 有更多的时间来产生相同的结果...
flatMap
,map
&的示例更实际地展示它。然后是flatten
和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
效率很高 Elapsed 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)
答案 2 :(得分:3)
从概念上讲,没有区别。实际上,flatten
更有效率,并传达了更清晰的意图。
通常,您不能直接使用identity
。它更像是作为参数传入或被设置为默认值的情况。编译器可以对其进行优化,但是你要为每个元素冒一个多余的函数调用。
当您需要flatMap
(map
以外的功能)后紧跟identity
时,您可以使用flatten
。