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

如何使用LINQ筛选累加时长低于阈值的工时数据子集

LINQ实现低于工时阈值的记录子集筛选

问题场景

开发员工排班应用时,需要统计指定时间范围内,两类不同薪资类型的工时累加值低于2250分钟(即37.5小时)的记录。目前通过两次调用.Sum()分别计算两类薪资对应工时再累加的求和逻辑可正常运行,但无法正确筛选出符合总时长要求的记录子集,现有分组后的代码片段如下:

g.Sum(x => x.Start >= start && x.End <= End ? x.Type1 : 0) +
g.Sum(x => x.Start >= start && x.End <= End ? x.Type2 : 0) <= 2250 ? .....
// then count the hours below here. 

该逻辑在总时长超过2250分钟时会直接返回0,无法生成符合要求的工时数据子集。

问题原因

现有逻辑存在两个明显问题:

  • 重复遍历分组内的记录做两次求和,存在不必要的性能损耗
  • 没有将总时长阈值判断作为分组的过滤条件,仅通过三元表达式做分支返回,不符合阈值的分组会直接走返回0的分支,无法保留符合要求的完整记录子集

正确实现方式

按照「先过滤时间范围→再按维度分组→再按总工时阈值筛选合格分组→最后输出需要的子集/统计值」的顺序写LINQ即可,参考代码如下:

var validShiftSet = shiftDataSource
    // 第一步:先把不在指定时间范围内的记录全过滤掉,后续不需要重复判断时间区间
    .Where(shift => shift.Start >= start && shift.End <= end)
    // 第二步:按你需要的维度分组,比如按员工ID、按周维度都可以,替换成实际的分组键即可
    .GroupBy(shift => shift.EmployeeId)
    // 第三步:筛选出组内总工时低于阈值的分组
    .Where(group => 
    {
        int total = 0;
        foreach (var item in group)
        {
            total += item.Type1 + item.Type2;
            // 数据量较大时可以加提前终止逻辑,累加已经超阈值就直接跳过该组,不用算完所有记录
            if (total > 2250) return false;
        }
        return total <= 2250;
    })
    // 第四步:组装你需要的结果,既可以拿原始记录子集,也可以直接算统计值
    .Select(group => new 
    {
        GroupKey = group.Key,
        // 该分组下所有符合阈值要求的原始工时记录,就是你要的子集
        ValidShiftRecords = group.ToList(),
        TotalMinutes = group.Sum(item => item.Type1 + item.Type2),
        TotalHours = Math.Round(group.Sum(item => item.Type1 + item.Type2) / 60.0, 2)
    })
    .ToList();

如果不需要做提前终止的性能优化,也可以把第三步的筛选逻辑写成更简洁的形式:

.Where(group => group.Sum(item => item.Type1 + item.Type2) <= 2250)

注意:如果Type1、Type2字段是可空数值类型,求和时需要写为(item.Type1 ?? 0) + (item.Type2 ?? 0),避免空引用引发报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 16:33:28