【问题标题】:Scala: some questions on flatMap and mapScala:关于 flatMap 和 map 的一些问题
【发布时间】:2018-10-26 14:56:40
【问题描述】:

我这里有一段 Scala 代码:https://scastie.scala-lang.org/1ey5T9lWQVOAozLoGVJthw

val days = List((1, (2, "a")), (1, (3, "b")), (1, (1, "c")), (2, (1, "aa")), (2, (2, "bb")))

println(days)

println(days.groupBy(_._1))
val r = days.groupBy(_._1).map(t => {
  println(s"t = $t, t._1 = ${t._1} t._2 = ${t._2} t._2.map(_._2) = ${t._2.map(_._2).toMap}")
  t._1 -> t._2.map(_._2).toMap
})


println(s"r = $r")

val rr = r.flatMap {
  case (k, v) => Some(k, v)
}

println(rr)

val rrr = r.map {
  case (k, v) => Some(k, v)
}

println(rrr)

程序运行后的输出:

List((1,(2,a)), (1,(3,b)), (1,(1,c)), (2,(1,aa)), (2,(2,bb)))
Map(2 -> List((2,(1,aa)), (2,(2,bb))), 1 -> List((1,(2,a)), (1,(3,b)), (1,(1,c))))
t = (2,List((2,(1,aa)), (2,(2,bb)))), t._1 = 2 t._2 = List((2,(1,aa)), (2,(2,bb))) t._2.map(_._2) = Map(1 -> aa, 2 -> bb)
t = (1,List((1,(2,a)), (1,(3,b)), (1,(1,c)))), t._1 = 1 t._2 = List((1,(2,a)), (1,(3,b)), (1,(1,c))) t._2.map(_._2) = Map(2 -> a, 3 -> b, 1 -> c)
r = Map(2 -> Map(1 -> aa, 2 -> bb), 1 -> Map(2 -> a, 3 -> b, 1 -> c))
Map(2 -> Map(1 -> aa, 2 -> bb), 1 -> Map(2 -> a, 3 -> b, 1 -> c))
List(Some((2,Map(1 -> aa, 2 -> bb))), Some((1,Map(2 -> a, 3 -> b, 1 -> c))))

我有一些问题:

1、为什么rrrrr不一样?

(1) 为什么rrMap,而rrrList? 我知道rrrListmap会对每个键值对进行操作,最后返回一个List。我对吗?但是为什么flatMap 会返回Map

(2) 为什么Somerrr 中? Some用来过滤掉None

2、在flatMap中,Some(k, v)会被解析成k->v

3、在flatMapSome(a -> (b -> c))会被解析成(a, (b, c))

至于 2 和 3,我很困惑为什么 tuple 和 Map 搞混了?我可能错了。

我是 Scala 新手。即使我阅读了一些教程,我仍然有太多的困惑。大多数教程都在flatMapListSeq 上给出了示例。

欢迎任何帮助。谢谢

【问题讨论】:

    标签: scala scala-collections


    【解决方案1】:

    mapflatMap 等大多数收集方法的结果类型取决于我们传递给它的函数的结果类型。

    这由 CanBuildFrom 隐式值确定。

    鉴于此,有一个基于 Tuple2Map 类型的 CanBuildFrom 实例。换句话说,如果您从传递给mapMap 的函数返回Tuple2,那么结果也是Map,但如果您返回Tuple2 以外的其他内容,则map 函数会选择下一个特定的CanBuildFrom,它基于Iterable

    rr的情况下,flatMap基本上调用flatten然后map。在flatten 操作期间,Option[Tuple2[A, B]] 被展平为仅Tuple2[A, B],因此Tuple2 被传递给map 函数,因此结果是Map

    对于rrr,结果不是Tuple2,而是Option[Tuple2[A, B]],所以不能在GenMapFactory.scala使用Map定义的CanBuildFrom

    要添加更多内容,请尝试以下代码,结果将是 Map

    val r3 = r.map {
      case (k, v) => (k, v)
    }
    
    println(r3) //r3 is a Map not a List
    

    【讨论】:

    • 在flatMap中,Some(a -> (b -> c))会被解析成(a, (b, c))?
    • @BAE (x -> y) 只是(x, y) 的替代语法。它无处不在,它不以任何方式特定于flatMap
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 2018-05-07
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多