scala - Scala:关于 flatMap 和 map 的一些问题
问题描述
我在这里有一段 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、为什么rr
和rrr
不同?
(1) 为什么rr
是 a Map
,但是rrr
是 a List
?我理解rrr
的是一个List
。map
将对每个键值对进行操作,最后返回一个List
. 我对吗?但是为什么要flatMap
返回一个Map
?
(2) 为什么Some
在rrr
?Some
用来过滤掉None
?
2、在flatMap
,Some(k, v)
会被解析成k->v
?
3、在flatMap
,Some(a -> (b -> c))
会被解析成(a, (b, c))
?
至于 2 和 3,我很困惑为什么 tuple 和 Map 搞混了?我可能错了。
我是 Scala 的新手。即使我阅读了一些教程,我仍然有太多的困惑。flatMap
大多数教程都提供了关于,List
的示例Seq
。
欢迎任何帮助。谢谢
解决方案
大多数集合方法的结果类型,如map
,flatMap
等,取决于我们传递给它的函数的结果类型。
这是由CanBuildFrom
隐含值决定的。
鉴于此,有一个基于类型的CanBuildFrom
实例。换句话说,如果您从传递给a的函数返回 a ,那么结果也是 a ,但如果您返回的不是函数,则选择基于的下一个特定值。Map
Tuple2
Tuple2
map
Map
Map
Tuple2
map
CanBuildFrom
Iterable
在的情况下rr
,flatMap
基本上是调用flatten
然后map
。在flatten
操作过程中,Option[Tuple2[A, B]]
is 展平为 just Tuple2[A, B]
,因此Tuple2
被传递给map
函数,因此结果是 a Map
。
在 的情况下rrr
,结果不是 a Tuple2
,而是Option[Tuple2[A, B]]
,所以它不能使用atCanBuildFrom
定义的。Map
GenMapFactory.scala
要添加更多内容,请尝试以下代码,结果将是Map
val r3 = r.map {
case (k, v) => (k, v)
}
println(r3) //r3 is a Map not a List
推荐阅读
- reactjs - 在 Antd 表单中切换可见性
- javascript - 如何使用 lodash 在数组中插入特定索引?
- angularjs - 无法实例化模块 angularUtils.directives.dirPagination 'angularUtils.directives.dirPagination' 不可用
- python - python不读取文件的第二行
- javascript - 无法在 React Chrome 扩展中调试单个浏览器操作 js 文件
- docker - Docker windows下的Kiwi TCMS问题
- reactjs - ReactJS Springboot JVM 和代理
- google-sheets - 如何在工作表中按相同条件对多个查询进行单次排序?
- facebook-graph-api - facebook开发者警报混乱
- arkit - 从 USDZ 文件到 glTF 文件的转换