映射到列表头部时理解 Scala Map 对象
Understanding the Scala Map object when mapping to the head of a list
您好,我有以下数据,想将其映射到第二个参数中的第一项。所以对于:
1 -> List((1,11))
1 -> List((1,1), (1,111))
我要:
(1,11)
(1,1)
当此数据在 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)
但是,当它位于 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)
当我映射到整个列表时,我得到了我所期望的,但当我直接调用它时却没有
scala> m.map(_._2)
res2: scala.collection.immutable.Iterable[List[(Int, Int)]] = List(List((1,11)), List((1,1), (1,111)))
我做以下任一操作也能得到我想要的结果:
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))
有人可以解释一下这是怎么回事吗?
这有点棘手,取决于地图的隐式参数 CanBuildFrom。根据函数 f 的输出类型,它将能够构建一个结构或另一个结构(它将由隐式 CanBuildFrom 构建)。
m.map(_._2.head) // The passed function retrieves a pair (Int, Int)
有一个从 (A, A) 到 Map[A,A] 的隐式 CanBuildFrom,该对象隐式传递给您的地图,这就是为什么在这种情况下返回的对象是 Map[Int, Int]
在另一种情况下你有
m.map(_._2) // The passed function retrieves a List[(Int, Int)]
List[A] 的隐式 CanBuildFrom 将构建一个 Iterable[A],在本例中是从 List[(Int, Int)] 到 Iterable[(Int, Int)]
scala.collection.immutable.Map
上的映射操作根据映射操作的 return 类型表现不同。
当Type Tuple2[T,P]的return类型if时:
Map 操作的输出结果是另一个 Map
,其中元组的第一个元素 _1
作为键,第二个元素 _2
作为值。
例如
scala> m.map(_ => 10 -> 1)
res14: scala.collection.immutable.Map[Int,Int] = Map(10 -> 1) // note the return type is Map.
当 return 类型不是 Tuple2:
当 return 类型不是 Tuple2 时,映射操作的输出是一个列表。
scala> m.map(_ => 10 )
res15: scala.collection.immutable.Iterable[Int] = List(10, 10) // note that the return type now is a List.
因此根据上述事实,对于值 Map(11 -> List((1,11)), 1 -> List((1,1)))
的 Map
,操作 m.map(_._2.head)
产生 Tuple2 值 (1, 11)
和 (1,1)
。由于每个 Tuple2 项的第一个值 (_1
) 是 1(即每个值的键是 1),(1,1)
覆盖 (1,11)
并且我们最终得到单个值 (1,1)
.
在其他情况下,map 操作没有 return 类型的 Tuple2,因此它导致 List
类型而不是 Map
类型,因此不同之处在于结果。
您好,我有以下数据,想将其映射到第二个参数中的第一项。所以对于:
1 -> List((1,11))
1 -> List((1,1), (1,111))
我要:
(1,11)
(1,1)
当此数据在 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)
但是,当它位于 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)
当我映射到整个列表时,我得到了我所期望的,但当我直接调用它时却没有
scala> m.map(_._2)
res2: scala.collection.immutable.Iterable[List[(Int, Int)]] = List(List((1,11)), List((1,1), (1,111)))
我做以下任一操作也能得到我想要的结果:
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))
有人可以解释一下这是怎么回事吗?
这有点棘手,取决于地图的隐式参数 CanBuildFrom。根据函数 f 的输出类型,它将能够构建一个结构或另一个结构(它将由隐式 CanBuildFrom 构建)。
m.map(_._2.head) // The passed function retrieves a pair (Int, Int)
有一个从 (A, A) 到 Map[A,A] 的隐式 CanBuildFrom,该对象隐式传递给您的地图,这就是为什么在这种情况下返回的对象是 Map[Int, Int]
在另一种情况下你有
m.map(_._2) // The passed function retrieves a List[(Int, Int)]
List[A] 的隐式 CanBuildFrom 将构建一个 Iterable[A],在本例中是从 List[(Int, Int)] 到 Iterable[(Int, Int)]
scala.collection.immutable.Map
上的映射操作根据映射操作的 return 类型表现不同。
当Type Tuple2[T,P]的return类型if时:
Map 操作的输出结果是另一个 Map
,其中元组的第一个元素 _1
作为键,第二个元素 _2
作为值。
例如
scala> m.map(_ => 10 -> 1)
res14: scala.collection.immutable.Map[Int,Int] = Map(10 -> 1) // note the return type is Map.
当 return 类型不是 Tuple2:
当 return 类型不是 Tuple2 时,映射操作的输出是一个列表。
scala> m.map(_ => 10 )
res15: scala.collection.immutable.Iterable[Int] = List(10, 10) // note that the return type now is a List.
因此根据上述事实,对于值 Map(11 -> List((1,11)), 1 -> List((1,1)))
的 Map
,操作 m.map(_._2.head)
产生 Tuple2 值 (1, 11)
和 (1,1)
。由于每个 Tuple2 项的第一个值 (_1
) 是 1(即每个值的键是 1),(1,1)
覆盖 (1,11)
并且我们最终得到单个值 (1,1)
.
在其他情况下,map 操作没有 return 类型的 Tuple2,因此它导致 List
类型而不是 Map
类型,因此不同之处在于结果。