2012-03-16 42 views
10

Ví dụ: làm cách nào để nhóm các bản ghi sau bằng cách GroupId bằng LINQ và tổng hợp tất cả các cột khác trong mỗi nhóm? (Như vậy, việc sáp nhập tất cả các hàng trong mỗi nhóm thành một)Làm thế nào để hợp nhất/tổng hồ sơ theo nhóm bằng LINQ?

var list = new List<Foo>() 
{ 
    new Foo() { GroupId = 0, ValueA = 10, ValueB = 100 }, 
    new Foo() { GroupId = 1, ValueA = 30, ValueB = 700 }, 
    new Foo() { GroupId = 1, ValueA = 40, ValueB = 500 }, 
    new Foo() { GroupId = 2, ValueA = 80, ValueB = 300 }, 
    new Foo() { GroupId = 2, ValueA = 20, ValueB = 200 }, 
    new Foo() { GroupId = 2, ValueA = 20, ValueB = 200 } 
}; 

Kết quả mong đợi là:

| GroupId | ValueA | ValueB | 
|---------|--------|--------| 
| 0 | 10 | 100 | 
| 1 | 70 | 1200 | 
| 2 | 120 | 700 | 

Trả lời

13
list.GroupBy(i => i.GroupId) 
    .Select(g => new { GroupId = g.Key, 
         ValueA = g.Sum(i => i.ValueA), 
         ValueB = g.Sum(i => i.ValueB)}); 

hoặc chỉ để cho vui, bạn có thể làm điều đó trong vòng một GroupBy cuộc gọi sử dụng quá tải của nó:

list.GroupBy(i => i.GroupId, 
     (key, groupedItems) => new { 
             GroupId = key, 
             ValueA = groupedItems.Sum(i => i.ValueA), 
             ValueB = groupedItems.Sum(i => i.ValueB), 
            }); 

hoặc bạn có thể sử dụng Aggregate để tránh iterating từng nhóm nhiều lần:

list.GroupBy(i => i.GroupId) 
    .Select(g => g.Aggregate((i1, i2) => new Foo{ GroupId = i1.GroupId, 
                ValueA = i1.ValueA + i2.ValueA, 
                ValueB = i1.ValueB + i2.ValueB, 
               })); 
3

Sử dụng GroupBy để thu thập Foo s thành các nhóm dựa trên GroupId của họ, và sau đó tạo ra một đối tượng mới cho mỗi "hàng" của kết quả (đối tượng đó có thể là một số Foo dựa trên mã bạn cung cấp, nhưng nó có thể dễ dàng là bất kỳ thứ gì khác, bao gồm cả loại ẩn danh). Tại thời điểm đó, bạn cũng sẽ tổng hợp các giá trị khác.

var sums = list.GroupBy(f => f.GroupId) 
       .Select(g => new Foo 
       { 
        GroupId = g.Key, 
        ValueA = g.Sum(f => f.ValueA), 
        ValueB = g.Sum(f => f.ValueB) 
       }).ToList(); 
5
var query = list.GroupBy(x=> x.GroupId) 
       .Select(g=> new 
        { 
        GroupId = g.Key, 
        ValueA = g.Sum(x => x.ValueA), 
        ValueB = g.Sum(x => x.ValueB) 
        }); 
0

Tránh các biểu thức lambda (gần như) và sử dụng một "thuần túy" LINQ cách:

var sums = from foo in list 
    group foo by foo.GroupId into groupings 
    orderby groupings.Key ascending 
    select new 
    { 
     GroupId = groupings.Key, 
     ValueA = groupings.Sum(g => g.ValueA), 
     ValueB = groupings.Sum(g => g.ValueB) 
    }; 

Tôi chỉ nghĩ rằng LINQ là một chút nhiều ngôn ngữ tự nhiên tìm kiếm, so với lambda (không có bất cứ điều gì sai với điều đó. ..)

Các vấn đề liên quan