Bre*_*dán 0 scala implicit scala-collections scala-implicits
嗨,我有以下数据,并希望将其映射到第二个参数中的第一项.因此对于:
1 -> List((1,11))
1 -> List((1,1), (1,111))
Run Code Online (Sandbox Code Playgroud)
我想要:
(1,11)
(1,1)
Run Code Online (Sandbox Code Playgroud)
当此数据在RDD中时,我可以执行以下操作:
scala> val m = sc.parallelize(Seq(11 -> List((1,11)), 1 -> List((1,1),(1,111))))
m: org.apache.spark.rdd.RDD[(Int, List[(Int, Int)])] = ParallelCollectionRDD[198] at parallelize at <console>:47
scala> m.map(_._2.head).collect.foreach(println)
(1,11)
(1,1)
Run Code Online (Sandbox Code Playgroud)
但是,当它在Map对象(groupBy的结果)中时,我得到以下内容:
scala> val m = Map(11 -> List((1,11)), 1 -> List((1,1)))
m: scala.collection.immutable.Map[Int,List[(Int, Int)]] = Map(11 -> List((1,11)), 1 -> List((1,1), (1,111)))
scala> m.map(_._2.head)
res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)
Run Code Online (Sandbox Code Playgroud)
当我映射到整个列表时,我得到了我期望的结果,但是当我打电话给它时
scala> m.map(_._2)
res2: scala.collection.immutable.Iterable[List[(Int, Int)]] = List(List((1,11)), List((1,1), (1,111)))
Run Code Online (Sandbox Code Playgroud)
如果我执行以下任一操作,我也可以得到我想要的结果:
scala> m.map(_._2).map(_.head)
res4: scala.collection.immutable.Iterable[(Int, Int)] = List((1,11), (1,1))
scala> m.values.map(_.head)
res5: Iterable[(Int, Int)] = List((1,11), (1,1))
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下这里发生了什么吗?
这有点棘手,取决于地图的隐式参数CanBuildFrom.根据函数的输出类型,它将能够构建一个结构或另一个结构(它将由隐式CanBuildFrom构建).
m.map(_._2.head) // The passed function retrieves a pair (Int, Int)
Run Code Online (Sandbox Code Playgroud)
从(A,A)到Map [A,A]有一个隐式的CanBuildFrom,该对象被隐式传递给你的地图,这就是为什么在这种情况下返回的对象是Map [Int,Int]
在另一种情况下,你有
m.map(_._2) // The passed function retrieves a List[(Int, Int)]
Run Code Online (Sandbox Code Playgroud)
List [A]的隐式CanBuildFrom将构建一个Iterable [A],在本例中是从List [(Int,Int)]到Iterable [(Int,Int)]