Map flatten and flatmap not equivalent

后端 未结 2 1815
野性不改
野性不改 2020-12-15 08:35

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

2条回答
  •  孤街浪徒
    2020-12-15 08:49

    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.

提交回复
热议问题