如何根据元组第一元素总结?

时间:2012-04-08 19:06:00

标签: scala tuples

我有一个3元组列表,如下所示[我为可读性添加了换行符]:

(2, 127, 3)
(12156, 127, 3)
(4409, 127, 2) <-- 4409 occurs 2x
(1312, 127, 12) <-- 1312 occurs 3x

(4409, 128, 1) <-- 
(12864, 128, 1)
(1312, 128, 1) <-- 
(2664, 128, 2)

(12865, 129, 1)
(183, 129, 1)
(12866, 129, 2)
(1312, 129, 10) <--

我想根据第一个条目总结一下。第一个条目应该是唯一的。

结果应如下所示:

(2, 127, 3)
(12156, 127, 3)
(4409, 127, 3) <- new sum = 3
(1312, 127, 23) <- new sum = 23

(12864, 128, 1)
(2664, 128, 2)

(12865, 129, 1)
(183, 129, 1)
(12866, 129, 2)

我如何在Scala中实现这一目标?

3 个答案:

答案 0 :(得分:6)

试试这个:

list groupBy {_._1} mapValues {v => (v.head._1, v.head._2, v map {_._3} sum)}

保留中间条目,它始终采用输入列表中出现的第一个条目。

答案 1 :(得分:3)

如果你可以忽略中间条目,那么:

val l = List(('a,'e,1), ('b,'f,2), ('a,'g,3), ('b,'h,4))
l.groupBy(_._1).mapValues(_.map(_._3).sum) 
// Map('b -> 6, 'a -> 4)

如果你必须保持中间条目:

l.groupBy(_._1).map { 
  case (_, values) =>
    val (a,b,_) = values.head
    (a, b, values.map(_._3).sum)
} 
// List(('b,'f,6), ('a,'e,4))

答案 2 :(得分:0)

你可以使用幺半群的概念。如果条目的前两个值构建键值,而剩余的关联值本身,则可以使用Map。

一旦你有了地图,你就可以这样做: Best way to merge two maps and sum the values of same key?