【发布时间】:2022-01-08 20:35:31
【问题描述】:
数据库包含带有设备特定代码的错误日志条目。如果代码为非 0 则错误为活动,为 0 则为无效。一次只能激活一个错误,因此存在设备“出错”和“未出错”的时间范围;但是可以同时发布许多其他错误代码(这与设备错误状态无关,此处感兴趣)。
我想计算设备“出错”的次数。不幸的是,我们不能假设错误总是交替出现(101, 0, 200, 0, 302, 0),但可能更混乱(3, 101, 0, 20, 202, 10, 0, 0, 102, ...)。在这里,每次的错误时间都是从第一个非零错误码开始计算到第一个0,所以第一个非零出现到第一个零出现之间的时间差,然后从第一个非零开始等等。
换句话说:
timeStamp code
100 101
200 0
300 500
350 501
400 0
--> Total Error Time = 200 ((200 - 100) + (400 - 300))
在循环中,这将是这样的任务:
totalErrorTime = 0;
previousError = errors.FirstOrDefault(x => x.code != 0);
errors.forEach(error => {
if (previousError.code == 0 && error.code != 0)
// Set first encountered non zero error code
previousError = error;
if (error.code == 0) {
// Encountered 0 error code, calculate difference
totalErrorTime += error.timeStamp - previousError.timeStamp;
// Set previous error to this error for lookahead
previousError = error;
}
}
但我想知道如何在 Linq 中执行类似的操作。到目前为止,我在想这样的事情:
var skippedErrors = errors;
result = errors
.Zip(skippedErrors.Skip(1).SkipWhile(x => x.code != 0), (a, b) => new
{
errorTime = b.timeStamp - a.timeStamp
})
.Select(x => new ErrorTimeResult(x.Sum(y => y.errorTime))));
但是,我认为SkipWhile() 部分并不安全。
如何在 Linq 中进行这些“前瞻”?我认为Zip() 是正确的方法,但我怎样才能确保只计算每个“错误阶段”一次?谢谢。
【问题讨论】:
-
在数据库级别执行此操作不是更简单、更高效吗?