Scala 地图展平和平面地图不等效

Scala 地图展平和平面地图不等效,scala,dictionary,case-class,Scala,Dictionary,Case Class,我想是的。但在这个例子中,情况并非如此。我想知道case类在其中扮演什么角色。如果我使用整数,两者都是等价的。但就我而言,我不能 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, dest

我想是的。但在这个例子中,情况并非如此。我想知道case类在其中扮演什么角色。如果我使用整数,两者都是等价的。但就我而言,我不能

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
屈服

Set((CTest(0),3), (CTest(1), 2))
鉴于

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
屈服

Set((CTest(0),0), (CTest(0),3), (CTest(1),0), (CTest(1),2))

知道为什么吗?

这是由于中间数据结构造成的

我将以你的例子的简单版本为例

val m = Map(CTest(0) -> List(0, 3), CTest(1) -> List(0, 2))
使用
flatMap
时,直接创建
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)
在这里,由于
Map
键的唯一性,将从结果中删除
(CTest(0),0)
(CTest(1),0)
。当您
flatMap
将其覆盖时,您将得到
Map
元组的
集合

在第二个示例中,映射并展平

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))

没有任何<代码> map <代码>或在过程中间创建的另一个唯一保存的数据结构。因此不会删除值。

看看
flatMap
的实现:

def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
  def builder = bf(repr) // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
  val b = builder
  for (x <- this) b ++= f(x).seq
  b.result
}
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.toIterable.flatMap {
    case (label, destNodes) => destNodes map {
      case nodes => (label, nodes) }
  }
  mapping
}
possibilities