问题
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)
Is there any difference between these two functions? When is it appropriate to use one over the other? Are there any tradeoffs?
回答1:
You can view flatMap(identity) as map(identity).flatten. (Of course it is not implemented that way, since it would take two iterations).
map(identity) gives you the same collection, so in the end it is the same as only flatten.
I would personally stick to flatten, since it is shorter/easier to understand and designed to exactly do this.
回答2:
Conceptually there is no difference in the result...
flatMapis taking bit more time to produce same result...
I will show it more practically with an example of 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
}
}
Both flatMap and flatten executed with same result after repeating several times
Conclusion : flatten is efficient
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)
回答3:
Conceptually, there is no difference. Practically, flatten is more efficient, and conveys a clearer intent.
Generally, you don't use identity directly. It's more there for situations like it getting passed in as a parameter, or being set as a default. It's possible for the compiler to optimize it out, but you're risking a superfluous function call for every element.
You would use flatMap when you need to do a map (with a function other than identity) immediately followed by a flatten.
来源:https://stackoverflow.com/questions/27005148/is-there-any-difference-between-flatten-and-flatmapidentity