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?
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.
Conceptually there is no difference in the result...
flatMap
is 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)
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