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

如何调整代码从List<DataRecord>筛选一小时内记录数最多的记录组?

如何筛选出一小时时间区间内记录数量最多的数据集?

先说说你的问题核心:原来的代码只按整点小时分组,完全没考虑跨整点的一小时窗口(比如10:50到11:50这种),所以才拿不到预期的3条记录。咱们来一步步解决这个问题。

先明确下需求和现状:
你有一个DataRecord类:

class DataRecord { 
    public double MeasuredValue { get; set; } 
    public DateTime MeasurementDate { get; set; } 
}

需要找出任意连续一小时区间(不管日期,只看时间范围)里记录数量最多的所有记录。比如你给的示例数据里,10:50-11:50这个区间包含3条记录,是所有可能区间里最多的,所以要返回这3条。

而你现在的代码是按Hour属性分组,相当于把所有11点整到11点59分的记录归为一组,17点的归为一组,这样最多只能拿到2条记录的组,完全没覆盖到跨整点的有效区间。

解决方案:遍历所有可能的一小时窗口

要解决这个问题,我们需要检查每一个可能的一小时时间窗口,统计每个窗口里的记录数,然后找到记录数最多的那个窗口里的所有记录。具体可以这么做:

第一步:先把数据按时间排序

先把所有记录按MeasurementDate从小到大排序,这样后续统计窗口记录的时候可以更高效,不用反复扫全部数据:

var sortedRecords = records.OrderBy(r => r.MeasurementDate).ToList();

第二步:逐个记录作为窗口起点,统计对应一小时内的记录

对每一条记录,我们把它的时间作为窗口的起始点,然后找出所有时间在[起始时间, 起始时间+1小时)范围内的记录,统计数量。同时跟踪记录数最多的窗口:

int maxRecordCount = 0;
List<DataRecord> bestWindowRecords = new List<DataRecord>();

for (int i = 0; i < sortedRecords.Count; i++)
{
    var windowStart = sortedRecords[i].MeasurementDate;
    var windowEnd = windowStart.AddHours(1);
    // 因为数据已经排序,从当前位置往后取,直到超出一小时窗口
    var currentWindowRecords = sortedRecords
        .Skip(i)
        .TakeWhile(r => r.MeasurementDate < windowEnd)
        .ToList();
    
    // 更新最大记录数和对应的窗口记录
    if (currentWindowRecords.Count > maxRecordCount)
    {
        maxRecordCount = currentWindowRecords.Count;
        bestWindowRecords = currentWindowRecords;
    }
}

运行这段代码后,bestWindowRecords里就是你要的预期结果——那3条记录。

可选:处理多个窗口记录数相同的情况

如果有多个不同的一小时窗口都有相同的最大记录数,你可能需要把这些窗口的记录都保留下来。这时候可以调整代码,用一个列表来存储所有符合条件的窗口:

int maxRecordCount = 0;
List<List<DataRecord>> allBestWindows = new List<List<DataRecord>>();

for (int i = 0; i < sortedRecords.Count; i++)
{
    var windowStart = sortedRecords[i].MeasurementDate;
    var windowEnd = windowStart.AddHours(1);
    var currentWindowRecords = sortedRecords
        .Skip(i)
        .TakeWhile(r => r.MeasurementDate < windowEnd)
        .ToList();
    
    if (currentWindowRecords.Count > maxRecordCount)
    {
        // 找到更大的记录数,清空之前的结果,添加当前窗口
        maxRecordCount = currentWindowRecords.Count;
        allBestWindows.Clear();
        allBestWindows.Add(currentWindowRecords);
    }
    else if (currentWindowRecords.Count == maxRecordCount)
    {
        // 避免重复添加同一个窗口(比如连续的记录属于同一个窗口)
        if (!allBestWindows.Any(w => w.First().MeasurementDate == windowStart))
        {
            allBestWindows.Add(currentWindowRecords);
        }
    }
}

// 如果需要把所有最佳窗口的记录合并成一个去重后的列表
var allMaxRecords = allBestWindows.SelectMany(w => w).Distinct().ToList();

为什么这个方法能行?

因为我们没有局限于整点小时的分组,而是考虑了每一条记录对应的一小时窗口,这样就不会漏掉任何可能的、包含最多记录的区间。而且因为数据已经排序,用Skip(i).TakeWhile的方式比每次遍历全部数据要高效不少,尤其是数据量较大的时候。


内容的提问来源于stack exchange,提问作者Erik T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:50:11