如何使用LINQ按组合并/汇总记录
本文关键字:记录 合并 组合 何使用 LINQ | 更新日期: 2023-09-27 18:28:07
例如,如何使用LINQ按GroupId
对以下记录进行分组,并对每组中的所有其他列求和?(从而将每组中的所有行合并为一行)
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 |
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,
}));
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)
});
使用GroupBy
根据GroupId
将Foo
收集到组中,然后为结果的每个"行"创建一个新对象(根据您给出的代码,该对象本身可以是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();
避免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)
};
我只是觉得与lambda相比,LINQ看起来更自然一些(并不是说有什么问题…)