2012-03-16 54 views
10

例如,如何使用LINQ將GroupId中的以下記錄分組,並對每個組中的所有其他列進行求和? (因此合併所有行各組中爲一個)如何使用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 } 
}; 

預期結果是:

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

回答

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

或只是爲了好玩,你可以使用它的過載一個GroupBy調用中做到這一點:

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

,或者您可以使用Aggregate避免迭代每組多少次:

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

使用GroupBy收集Foo s轉換基於它們GroupId組,然後爲每個新的對象結果的「行」(該對象可以是基於您給出的代碼的Foo本身,但它可能很容易就是其他任何內容,包括匿名類型)。在那一點上,你也將總結其他值。

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

避免的lambda表達式(幾乎),並使用了「純粹的」 LINQ方式:

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

我只是認爲LINQ是一個比較自然語言看,相比於拉姆達(不是說有什麼不妥。 ..)