2012-04-08 14 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

答えて

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

あなたはモノイドの概念を使うことができます。エントリの最初の2つの値がキー値を構成し、残りの値が関連値そのものを構築する場合は、マップを使用できます。あなたは地図を持っていたら

あなたは次のように進行してもよい: Best way to merge two maps and sum the values of same key?

関連する問題