2012-04-08 20 views
5

tôi có một danh sách 3-tuple như sau [Tôi thêm vào ngắt dòng cho dễ đọc]:Làm thế nào để tổng hợp dựa trên một Tuples đầu tiên elem?

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

Tôi muốn tổng hợp dựa trên các mục nhập đầu tiên. Mục nhập đầu tiên phải là duy nhất.

Kết quả sẽ giống như thế này:

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

Làm thế nào tôi có thể đạt được điều này trong Scala?

+0

Bạn quan tâm đến mục giữa? – dhg

Trả lời

6

Hãy thử điều này:

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

Các mục trung lưu được giữ nguyên và luôn luôn có mục đầu tiên xuất hiện trong danh sách đầu vào.

3

Nếu bạn chỉ có thể bỏ qua các mục nhập trung bình, sau đó:

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) 

Nếu bạn có để giữ cho các mục nhập trung xung quanh:

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

Bạn có thể sử dụng khái niệm về hình đơn. Nếu hai giá trị đầu tiên của các mục nhập của bạn tạo các giá trị khóa và giá trị liên kết còn lại, bạn có thể sử dụng Bản đồ.

Một khi bạn có một bản đồ bạn có thể tiến hành như thế này: Best way to merge two maps and sum the values of same key?