繁体   English   中英

Scala-按键减少元组列表

[英]Scala - Reduce list of tuples by key

我有一个包含userIdpoint的元组列表。 我想按键组合或缩小此列表。

val points: List[(Int, Double)] = List(
  (1, 1.0),
  (2, 3.2),
  (4, 2.0),
  (1, 4.0),
  (2, 6.8)
)

预期结果应如下所示:

List((1, 5.0), (2, 10.0), (4, 2.0))

我尝试使用groupBymapValue ,但出现错误:

val aggrPoint: Map[Int, Double] = incomes.groupBy(_._1).mapValues(seq => seq.reduce(_._2 + _._2))

Error:(16, 180) type mismatch;
 found   : Double
 required: (Int, Double)

我在做什么错,有没有惯用的方式来做到这一点?

PS),我发现,在星火aggregateByKey做这件工作。 但是,Scala中有内置方法吗?

您可以map在元组mapValues他们的第二个元素,然后sum它们如下:

points.groupBy(_._1).mapValues( _.map(_._2).sum ).toList
// res1: List[(Int, Double)] = List((2,10.0), (4,2.0), (1,5.0))

我在做什么错,有没有惯用的方式来做到这一点?

让我们一步一步去看看你在做什么错 (我将使用REPL

首先让我们定义点

scala> val points: List[(Int, Double)] = List(
     |   (1, 1.0),
     |   (2, 3.2),
     |   (4, 2.0),
     |   (1, 4.0),
     |   (2, 6.8)
     | )
points: List[(Int, Double)] = List((1,1.0), (2,3.2), (4,2.0), (1,4.0), (2,6.8))

如您所见,您具有List[Tuple2[Int, Double]]因此当您将groupBymapValues做为

scala> points.groupBy(_._1).mapValues(seq => println(seq))
List((2,3.2), (2,6.8))
List((4,2.0))
List((1,1.0), (1,4.0))
res1: scala.collection.immutable.Map[Int,Unit] = Map(2 -> (), 4 -> (), 1 -> ())

您可以再次看到seq对象是List[Tuple2[Int, Double]]但只包含成组的tuple作为list

因此,当您应用seq.reduce(_._2 + _._2)reduce函数接受Tuple2[Int, Double]两个输入,但输出仅为Double ,与预期的seq上的下一次迭代不匹配输入是Tuple2[Int, Double ] 多数民众赞成在主要问题 您所需要做的就是匹配输入和输出类型,以reduce功能

一种方法是将Tuple2[Int, Double]匹配为

scala> points.groupBy(_._1).mapValues(seq => seq.reduce{(x,y) => (x._1, x._2 + y._2)})
res6: scala.collection.immutable.Map[Int,(Int, Double)] = Map(2 -> (2,10.0), 4 -> (4,2.0), 1 -> (1,5.0))

但这不是您想要的输出,因此您可以从简化的Tuple2[Int, Double]提取double值Tuple2[Int, Double]如下所示:

scala> points.groupBy(_._1).mapValues(seq => seq.reduce{(x,y) => (x._1, x._2 + y._2)}._2)
res8: scala.collection.immutable.Map[Int,Double] = Map(2 -> 10.0, 4 -> 2.0, 1 -> 5.0)

或者您可以在应用reduce功能之前使用map

scala> points.groupBy(_._1).mapValues(seq => seq.map(_._2).reduce(_ + _))
res3: scala.collection.immutable.Map[Int,Double] = Map(2 -> 10.0, 4 -> 2.0, 1 -> 5.0)

希望解释清楚清楚,可以理解您的错误,并且您必须已经了解了reduce函数的工作原理

使用collect

points.groupBy(_._1).collect{
   case e => e._1 -> e._2.map(_._2).sum
}.toList
//res1: List[(Int, Double)] = List((2,10.0), (4,2.0), (1,5.0))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM