可能有很多方法可以做到这一点。我会试一试:
我假设您希望单独处理不同的标签。这是我的方法:
-
按标记对条目分组。
-
每组:
-
从列表开头删除值为0的所有条目。
-
如果有两个或多个具有相同值的相邻条目,则只保留第一个条目。
-
将1和0压缩在一起以计算时间跨度。
-
最后将每组的结果展平
我使用了以下测试数据:
var list = new List<TagData> {
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:09:00.000"), Tag = "extrg_01", Value = 0 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:10:00.000"), Tag = "extrg_01", Value = 1 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:10:00.000"), Tag = "extrg_02", Value = 1 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:12:02.000"), Tag = "extrg_01", Value = 1 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:15:02.000"), Tag = "extrg_01", Value = 0 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:16:01.000"), Tag = "extrg_01", Value = 0 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:15:02.000"), Tag = "extrg_02", Value = 0 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:25:50.000"), Tag = "extrg_01", Value = 1 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:45:11.000"), Tag = "extrg_01", Value = 0 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:25:50.000"), Tag = "extrg_02", Value = 1 },
new TagData { Timestamp = DateTime.Parse("2018-12-01 00:45:11.000"), Tag = "extrg_02", Value = 0 },
};
类定义:
class TagData
{
public DateTime Timestamp { get; set; }
public string Tag { get; set; }
public double Value { get; set; }
}
class TagSummary
{
public DateTime TimestampStart { get; set; }
public DateTime TimestampEnd { get; set; }
public string Tag { get; set; }
public TimeSpan TimeSpan => TimestampEnd - TimestampStart;
}
代码:
var summaries =
list.GroupBy(tagdata => tagdata.Tag) // Step (1)
.Select(group => // Step (2)
{
var data = group
.SkipWhile(tagdata => tagdata.Value == 0) // Step (2.1)
.Aggregate(new List<TagData>(), (acc, tagdata) => // Step (2.2)
{
if (acc.LastOrDefault()?.Value != tagdata.Value)
acc.Add(tagdata);
return acc;
});
var ones = data.Where(datatag => datatag.Value == 1);
var zeros = data.Where(datatag => datatag.Value == 0);
var result = ones.Zip(zeros, (startTag, endTag) => { // Step (2.3)
return new TagSummary { TimestampStart = startTag.Timestamp, TimestampEnd = endTag.Timestamp, Tag = startTag.Tag };
});
return result;
})
.SelectMany(x => x); // Step (3)
Console.WriteLine("timestamp_start | timestamp_end | tag | nrOfSeconds");
foreach (var summary in summaries)
Console.WriteLine($"{summary.TimestampStart:yyyy-MM-dd HH:mm:ss} | {summary.TimestampEnd:yyyy-MM-dd HH:mm:ss} | {summary.Tag,-8} | {summary.TimeSpan.TotalSeconds:0}");
输出如您指定的那样:
timestamp_start | timestamp_end | tag | nrOfSeconds
2018-12-01 00:10:00 | 2018-12-01 00:15:02 | extrg_01 | 302
2018-12-01 00:25:50 | 2018-12-01 00:45:11 | extrg_01 | 1161
2018-12-01 00:10:00 | 2018-12-01 00:15:02 | extrg_02 | 302
2018-12-01 00:25:50 | 2018-12-01 00:45:11 | extrg_02 | 1161