我在这里有一段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
是Map
,但rrr
是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,我很困惑为什么元组和地图混在一起?我可能错了。
我是Scala的新手。即使我阅读了一些教程,我仍然有太多的困惑。大多数教程都提供了flatMap
List
,Seq
。
欢迎任何帮助。感谢
答案 0 :(得分:2)
大多数收集方法(如map
,flatMap
等)的结果类型取决于我们传递给它的函数的结果类型。
这由CanBuildFrom
隐含值确定。
鉴于此,基于CanBuildFrom
的{{1}}类型有Map
个实例。换句话说,如果您从传递给Tuple2
的{{1}}的函数返回Tuple2
,那么结果也是map
,但是如果您返回的内容不是Map
{1}} 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
。
要添加更多内容,请尝试以下代码,结果将为CanBuildFrom
Map