如何使用Linq实现按Amount连续相同值分组?
按连续相同Amount字段分组的Linq实现方案
需求是按Amount字段分组,但仅将连续出现的相同Amount值归为同一组。常规的GroupBy会把所有相同Amount的项合并,无法满足连续分组的要求,比如测试数据中最后一个Amount=100的项需要单独成组。
测试数据
{ { 0, 100 }, { 1, 100 }, { 2, 10 }, { 3, 100 } }
预期结果
Group1: { {0,100}, {1,100} } Group2: { {2,10} } Group3: { {3,100} }
常规GroupBy的实际结果
Group1: { {0,100}, {1,100}, {3,100} } Group2: { {2,10} }
当前代码(不符合需求)
class MyClass { public int Index {get; set;} public int Amount {get; set;} } var data = new List<MyClass> { new MyClass{Index=0,Amount=100}, new MyClass{Index=1,Amount=100}, new MyClass{Index=2,Amount=10}, new MyClass{Index=3,Amount=100} }; var itemsByAmount = data.GroupBy(d => d.Amount).Select(gd => gd.Select(d => d));
解决方案:用Aggregate生成组标识后分组
可以通过Aggregate方法追踪每个元素的前一个Amount值,给连续相同的元素分配同一个组ID,不同的则递增组ID,最后按组ID分组即可实现需求:
// 生成带组ID的临时集合 var groupedWithId = data.Aggregate(new List<(MyClass Item, int GroupId)>(), (acc, current) => { if (acc.Count == 0) { acc.Add((current, 0)); } else { var lastGroupId = acc.Last().GroupId; var lastAmount = acc.Last().Item.Amount; // 当前Amount和前一个不同则组ID+1 var newGroupId = current.Amount == lastAmount ? lastGroupId : lastGroupId + 1; acc.Add((current, newGroupId)); } return acc; }); // 按组ID分组并整理结果 var consecutiveGroups = groupedWithId .GroupBy(x => x.GroupId) .Select(g => g.Select(x => x.Item)) .ToList();
逻辑说明
- 使用
Aggregate遍历集合,维护一个包含元素和组ID的临时列表。 - 第一个元素直接分配组ID 0。
- 后续元素对比前一个元素的
Amount:相同则沿用前一个组ID,不同则组ID加1。 - 最后按组ID分组,得到连续相同
Amount的分组结果。
内容的提问来源于stack exchange,提问作者theateist
相关产品推荐
相关产品推荐

