我有一个元组列表,像这样:
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
但是,在这样的地图之间来回转换似乎是不必要的冗长和昂贵。有更好的方法吗?
答案 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)
可以使用groupBy
和groupMap
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)))