2012-04-08 108 views
5

我有一个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中实现这一目标?

+0

你在意中间的入口? – dhg 2012-04-08 19:10:30

回答

6

试试这个:

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

的中间条目被保留下来并且总是将第一条出现在输入列表中。

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))