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

C#按年、员工代码累加月度TotalOt值(优化性能)

优化加班累计数据的计算性能方案

现有代码

namespace Datas
{
    public class OtOverviewData
    {
        public int Month { get; set; }
        public int Year { get; set; }

        public List<OtOverviewItem> ListItems { get; set; } = new List<OtOverviewItem>();
    }

    public class OtOverviewItem
    {
        public string EmployeeCode { get; set; }
        public double TotalOt { get; set; } = 0;
    }
}

List<OtOverviewData> otData = new List<OtOverviewData>(); // 手动填充数据

var otAccumulateData = otData; // 注意:此处仅为引用赋值,并非真正克隆数据

需求说明

需要对otAccumulateData中的TotalOt字段,按相同年份(Year)、相同员工编码(EmployeeCode),以月度递增规则累加:

  • 2月累计值 = 1月数据值 + 2月原始数据值
  • 3月累计值 = 1月数据值 + 2月数据值 + 3月原始数据值
    此前采用嵌套for循环实现,性能不佳,寻求更高效的实现方式。

优化实现方案

核心思路

  1. 修正数据克隆问题:原代码的引用赋值会导致修改累计数据时同步改动原集合,需创建深拷贝的新集合避免副作用。
  2. 分组+排序+单次累加:先按Year和EmployeeCode分组,每组内按Month升序排序,再通过一次遍历完成累计计算,避免嵌套循环的重复遍历开销。

代码实现

// 1. 深拷贝原数据,隔离原集合与累计集合
var otAccumulateData = otData
    .Select(od => new OtOverviewData
    {
        Year = od.Year,
        Month = od.Month,
        ListItems = od.ListItems.Select(item => new OtOverviewItem
        {
            EmployeeCode = item.EmployeeCode,
            TotalOt = item.TotalOt
        }).ToList()
    })
    .ToList();

// 2. 按年份+员工编码分组,整合所有月度数据
var employeeMonthlyGroups = otAccumulateData
    .SelectMany(od => od.ListItems.Select(item => new 
    {
        od.Year,
        od.Month,
        item.EmployeeCode,
        item.TotalOt
    }))
    .GroupBy(x => new { x.Year, x.EmployeeCode });

// 3. 每组按月份升序遍历,计算累计值并更新回集合
foreach (var group in employeeMonthlyGroups)
{
    double accumulatedOt = 0;
    foreach (var monthlyData in group.OrderBy(x => x.Month))
    {
        accumulatedOt += monthlyData.TotalOt;
        // 定位到对应数据项并更新累计值
        var targetItem = otAccumulateData
            .First(od => od.Year == group.Key.Year && od.Month == monthlyData.Month)
            .ListItems
            .First(item => item.EmployeeCode == group.Key.EmployeeCode);
        targetItem.TotalOt = accumulatedOt;
    }
}

性能优势

  • 利用Linq的GroupBy哈希表分组逻辑,分组操作时间复杂度接近O(n),远优于嵌套循环的O(n²)。
  • 每组仅需一次排序+一次遍历即可完成累加,避免了重复遍历整个集合的冗余操作。
  • 逻辑清晰,后续维护成本更低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 12:27:25