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

如何用最短方式或LINQ查询移除分组列表中的非连续行?

移除LINQ分组后不连续SequenceId记录的解决方案

你已经通过LINQ获取了按SequenceSource分组、且每组内按SequenceId升序排序的List<List<InboxProcessingDto>>,需求是移除每组中从第一个元素开始出现断连的后续记录,只保留开头的连续序列(例如SequenceId为22、23、27、28的组仅保留22、23;2、3、17、28、29的组仅保留2、3)。

实现思路

由于每组数据已按SequenceId排序,我们只需保留从第一个元素开始的最长连续序列:

  • 以组内第一个元素的SequenceId为基准
  • 每个连续元素的SequenceId应等于基准Id + 元素在序列中的索引
  • 一旦遇到不满足该条件的元素,后续所有元素均为断连部分,直接截断

修改后的完整LINQ查询

await _context.Inboxes
    .Join(_context.InboxProcessingOffsets, 
          x => x.SequenceSource, 
          y => y.Source, 
          (x, y) => new InboxProcessingDto { Inbox = x, InboxProcessingOffset = y })
    .Where(i => i.Inbox.Status == InboxStatus.New)
    .Take(100)
    .ToListAsync()
    .ContinueWith(t => t.Result
        .GroupBy(i => i.Inbox.SequenceSource)
        .Select(grp => 
        {
            var sortedItems = grp.OrderBy(i => i.Inbox.SequenceId).ToList();
            if (!sortedItems.Any()) return sortedItems;

            var baseSeqId = sortedItems[0].Inbox.SequenceId;
            // 找到第一个断连的元素索引
            var breakPoint = sortedItems.FindIndex((item, idx) => item.Inbox.SequenceId != baseSeqId + idx);
            
            // 若全部连续则返回完整列表,否则返回断点前的元素
            return breakPoint == -1 ? sortedItems : sortedItems.Take(breakPoint).ToList();
        })
        .ToList());

代码说明

  1. 先通过ToListAsync()异步获取初始数据集,再通过ContinueWith处理分组和连续序列过滤(避免在EF查询中使用客户端无法转换的逻辑)
  2. 对每个分组:
    • 排序并转为List以便后续索引操作
    • 空分组直接返回
    • 用FindIndex定位第一个不满足连续条件的元素位置
    • 根据断点位置返回对应的连续子列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:56:06