You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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();

逻辑说明

  1. 使用Aggregate遍历集合,维护一个包含元素和组ID的临时列表。
  2. 第一个元素直接分配组ID 0。
  3. 后续元素对比前一个元素的Amount:相同则沿用前一个组ID,不同则组ID加1。
  4. 最后按组ID分组,得到连续相同Amount的分组结果。

内容的提问来源于stack exchange,提问作者theateist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:48:23