I thought that Scala construct map(f).flatten
was equivalent to flatMap(f)
. But with this example, it is not the case. I wonder what is the role of the case class in it. If I use integers, both are equivalent. But in my case, I cannot.
case class CTest(v: Int)
val s = Set(Map(CTest(0) -> List(0, 3), CTest(1) -> List(0, 2)))
val possibilities = s flatMap { m =>
val mapping = m flatMap {
case (label, destNodes) => destNodes map {
case nodes => (label, nodes) }
}
mapping
}
possibilities
Yields
Set((CTest(0),3), (CTest(1), 2))
whereas
case class CTest(v: Int)
val s = Set(Map(CTest(0) -> List(0, 3), CTest(1) -> List(0, 2)))
val possibilities = s flatMap { m =>
val mapping = m map {
case (label, destNodes) => destNodes map {
case nodes => (label, nodes) }
}
mapping.flatten
}
possibilities
yields
Set((CTest(0),0), (CTest(0),3), (CTest(1),0), (CTest(1),2))
Any idea why?
This happens due to intermediate data structures.
I'll take simple version of your example.
val m = Map(CTest(0) -> List(0, 3), CTest(1) -> List(0, 2))
When using flatMap
you directly create a Map[CTest, Int]
scala> m flatMap {
| case (label, destNodes) => destNodes map {
| case nodes => (label, nodes) }
| }
res3: scala.collection.immutable.Map[CTest,Int] = Map(CTest(0) -> 3, CTest(1) -> 2)
In here, due to the uniqueness of the keys of Map
, (CTest(0), 0)
and (CTest(1), 0)
will be dropped from the result. when you flatMap
it over set, you will get a Set
of Tuples
which were in the Map
.
In your second example, you map and flatten.
val mapping = m map {
| case (label, destNodes) => destNodes map {
| case nodes => (label, nodes) }
| }
mapping: scala.collection.immutable.Iterable[List[(CTest, Int)]] = List(List((CTest(0),0), (CTest(0),3)), List((CTest(1),0), (CTest(1),2)))
mapping.flatten
res4: scala.collection.immutable.Iterable[(CTest, Int)] = List((CTest(0),0), (CTest(0),3), (CTest(1),0), (CTest(1),2))
There isn't any Map
or another uniqueness preserved data structure created in the middle of the process. So values are not dropped.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With