为什么Scala Map上的.map.flatten和flatMap会返回不同的结果?

Bor*_*ris 2 scala

我听说很多人都说flatMapmap+ 相似flatten.例如,答案.

相当不同吧?
因为flatMap将a String视为一个序列Char,它会将生成的字符串列表展平为一系列字符(Seq[Char]).
flatMap是的组合mapflatten,所以它首先运行map上的序列,然后运行flatten给出所示的结果.

但是我今天遇到了一些代码问题.结果mapflatMap似乎有所不同.这是我的代码

object ListDemo {
  def main(args: Array[String]): Unit = {
    val map1 = Map("a" -> List(1 ->11,1->111), "b" -> List(2 -> 22, 2 ->222)).map(_._2).flatten
    val map2 = Map("a" -> List(1 ->11,1->111), "b" -> List(2 -> 22, 2 ->222)).flatMap(_._2)
    map1.foreach(println)
    println()
    map2.foreach(println)
  }
}
Run Code Online (Sandbox Code Playgroud)

结果不是预期的.

(1,11)
(1,111)
(2,22)
(2,222)

(1,111)
(2,222)
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

sep*_*p2k 7

当调用.map(f)一个Map具有f返回(K, V)某些K和V(不一定是相同的K和V类型原始的Map),其结果将是一个Map[K, V].否则,如果f返回其他(非对)类型T,结果将是Iterable[T].因此,Map如果函数返回一对,Iterable则返回它.

在你的情况下,函数返回List[(Int, Int)],因此结果是Iterable[List[(Int, Int)]]- 而不是Map.在.flatten随后变成一本Iterable[(Int, Int)].

flatMap直接使用时,你直接得到(Int, Int)对,因此结果将是Map[Int, Int]- 而不是Iterable[(Int, Int)].并且由于Maps不允许重复键,因此Map包含的元素少于Iterable.

  • @ genius-pig因为它们在地图中被"111"和"222""覆盖",它们具有相同的键 (2认同)