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

C# DataTable删除间隔60秒内同ID同账单编码重复记录方案咨询

C# DataTable按时间间隔去重实现方案

核心逻辑

  1. 按相同的IdNumber和BillingCode对记录分组
  2. 每组内按EntryDate升序排序,保证最早的记录在前
  3. 遍历每组内的排序后记录,仅保留与上一条保留记录的时间间隔>60秒的记录

完整Linq实现

引用命名空间

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

核心处理代码

// 假设源DataTable名为sourceDt
var filteredRows = sourceDt.AsEnumerable()
    // 按IdNumber和BillingCode分组
    .GroupBy(row => new { 
        IdNumber = row.Field<string>("IdNumber"), 
        BillingCode = row.Field<int>("BillingCode") 
    })
    .SelectMany(group => {
        // 每组内按EntryDate升序排序
        var sortedGroup = group.OrderBy(row => row.Field<DateTime>("EntryDate")).ToList();
        var keepRows = new List<DataRow>();
        DateTime? lastKeepTime = null;
        foreach(var row in sortedGroup)
        {
            var currentTime = row.Field<DateTime>("EntryDate");
            // 第一条直接保留,和上一条保留记录间隔超过60秒也保留
            if(!lastKeepTime.HasValue || (currentTime - lastKeepTime.Value).TotalSeconds > 60)
            {
                keepRows.Add(row);
                lastKeepTime = currentTime;
            }
        }
        return keepRows;
    })
    .ToList();

// 生成新的去重后DataTable
DataTable resultDt = filteredRows.Any() ? filteredRows.CopyToDataTable() : sourceDt.Clone();

原表直接删除多余行的实现

如果不需要保留原数据,可以直接在原DataTable上操作:

// 计算要删除的行
var deleteRows = sourceDt.AsEnumerable().Except(filteredRows).ToList();
foreach(var row in deleteRows)
{
    sourceDt.Rows.Remove(row);
}
sourceDt.AcceptChanges();

说明

DataTable原生的Select方法仅支持简单条件过滤,无法处理这种依赖前后行关系的滑动窗口判断,结合Linq是当前最高效的实现方式,测试完全匹配你给出的样例输入输出要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:36:03