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

如何使用Linq根据前瞻条件计算设备错误日志的总错误时长

Linq实现设备错误总时长统计方案

问题背景

某数据库存储设备错误日志,每条日志包含时间戳与错误码,规则如下:

  • 错误码非0代表错误激活,为0代表错误未激活
  • 同一时间设备最多一个活跃错误,错误时长从首次非0错误上报时间开始,到首次0错误码上报时间结束
  • 上报顺序不固定,可能存在连续非0、连续0的情况,需正确统计多段错误时长的总和

示例:

timeStampcode
100101
2000
300500
350501
4000

总错误时长为 (200-100)+(400-300)=200

原有实现问题

你尝试的Zip+SkipWhile方案存在逻辑缺陷:SkipWhile是全局跳过序列开头的非0码,无法分段识别每个错误周期的起止,因此不能适配多段错误的场景。

推荐实现方案

这类带状态遍历的场景,使用Linq的Aggregate累加器是最优选择,它可以在遍历过程中携带自定义状态,完全对齐原有循环的逻辑:

// 遍历日志,累计错误总时长
long totalErrorTime = errors.Aggregate(
    // 初始化状态:未处于错误中,起始时间为0,总时长为0
    new { IsInError = false, StartTime = 0L, Total = 0L },
    (state, currLog) => 
    {
        // 场景1:当前未处于错误,遇到非0码,开启新错误周期
        if (!state.IsInError && currLog.code != 0)
        {
            return new 
            {
                IsInError = true,
                StartTime = currLog.timeStamp,
                Total = state.Total
            };
        }
        // 场景2:当前处于错误中,遇到0码,结算当前周期时长
        if (state.IsInError && currLog.code == 0)
        {
            return new 
            {
                IsInError = false,
                StartTime = 0L,
                Total = state.Total + (currLog.timeStamp - state.StartTime)
            };
        }
        // 其他场景:状态不变直接返回
        return state;
    }).Total;

// 包装为你需要的返回结果
var result = new ErrorTimeResult(totalErrorTime);

方案优势

  • 时间复杂度O(n),仅遍历一次日志序列,性能与原生循环一致
  • 自动兼容所有边界场景:连续非0码仅记录第一个的时间,连续0码仅结算一次时长,未结束的错误周期(日志结尾无0收尾)默认不统计(如果需要统计到当前时间,遍历结束后判断IsInError状态补算时长即可)

可选Zip实现方案

如果坚持用Zip思路,可先筛选状态切换点再配对计算,适配.NET 6及以上版本:

long totalErrorTime = errors
    // 补前导0码节点,兼容第一条日志就是非0的场景
    .Prepend(new { timeStamp = 0L, code = 0 })
    // 相邻两条日志配对,识别状态切换点
    .Zip(errors, (prev, curr) => new { prev.code, curr.code, curr.timeStamp })
    // 仅保留错误开始(0切非0)、错误结束(非0切0)的节点
    .Where(x => (x.prev.code == 0 && x.curr.code != 0) || (x.prev.code != 0 && x.curr.code == 0))
    // 每两个节点为一组,对应一个错误周期的起止
    .Chunk(2)
    // 过滤掉未结束的错误周期(只有开始没有结束)
    .Where(c => c.Length == 2)
    // 累加每个周期的时长
    .Sum(c => c[1].timeStamp - c[0].timeStamp);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:36:03