按第一个元素对元组列表进行分组,获取第二个元素的平均值

时间:2019-07-24 13:28:01

标签: scala

我有一个元组列表,像这样:

val list = List((1, 20), (2, 20), (1, 30), (2, 40), (2, 60))

我想将其映射到元组列表,其中:

  

第一个元素是唯一的。
  第二个元素是从具有相同第一个值的元组中平均得到的。

即对于上面的列表,映射到:List((1, 25), (2, 40))

我想我可以这样做:

list.groupBy(_._1)
  .map { case (key, value) =>
    (key, value.map(_._2).sum / value.length)}.toList

但是,在这样的地图之间来回转换似乎是不必要的冗长和昂贵。有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

您可能会使用Scala 2.13的{​​{3}}使它的冗长程度降低一些:

// val tuples = List((1, 20), (2, 20), (1, 30), (2, 40), (2, 60))
tuples.groupMap(_._1)(_._2).mapValues(vs => vs.sum / vs.size).toList
// List((1, 25), (2, 40))

请注意groupMap的中间结果:

tuples.groupMap(_._1)(_._2)
// Map(1 -> List(20, 30), 2 -> List(20, 40, 60))

答案 1 :(得分:1)

可以使用groupBygroupMap

list.groupBy(_._1).view.mapValues(value => value.map(_._2).sum / value.length).toList

输出: List((1,25), (2,40))

list.groupMap(_._1)(_._2).view.mapValues(value => value.sum / value.size).toList

输出: List((1,25), (2,40))

 list.groupMap(_._1)(_._2)

输出: Map(1 -> List(20, 30), 2 -> List(20, 40, 60))

 list.groupBy(_._1)

输出: HashMap(1 -> List((1,20), (1,30)), 2 -> List((2,20), (2,40), (2,60)))

  list.groupBy(_._2)

输出: HashMap(20 -> List((1,20), (2,20)), 60 -> List((2,60)), 40 -> List((2,40)), 30 -> List((1,30)))