我正在尝试对列表中的数据进行一些手动验证。
我有一个MachineryRecord类,我按JobNumber排序然后分组,现在我需要在每个具有重叠时间的分组列表中找到任何结果,例如。结束时间的开始时间与另一个记录StartTime重叠为EndTime。
到目前为止,这就是我所拥有的:
int invalidCount = 0;
var sorted = _machineRecords.OrderBy(x => x.StartTime).ToList();
var grouped = sorted.GroupBy(x => x.JobNumber).ToList();
foreach(IGrouping<int,MachineryRecord> mac in grouped)
{
var queryResults = mac.//Linq query to find overlapping times
invalidCount += queryResults.Count;
}
if(invalidCount > 0)
return false;
else
return true;
并且是一个MachineRecord对象的缩减版本:
public class MachineryRecord
{
public int ID { get; set; }
public float StartTime { get; set; }
public float EndTime { get; set; }
}
所以我的问题是实现这个目标的linq查询是什么?
感谢您的帮助。
答案 0 :(得分:3)
如果a
和b
假设开始时间始终在结束时间之前,则a.StartTime < b.EndTime
和a.EndTime > b.StartTime
会有两个时间间隔重叠。因此,这可以表示如下。
var invalidCount = _machineRecords.Count(a =>
_machineRecords.Any(b =>
(a.ID != b.ID) &&
(a.JobNumber == b.JobNumber) &&
(a.StartTime < b.EndTime) &&
(a.EndTime > b.StartTime)));
包括invalidCount
的最终检查,这可以简化为单个返回语句。
return !_machineRecords.Any(a =>
_machineRecords.Any(b =>
(a.ID != b.ID) &&
(a.JobNumber == b.JobNumber) &&
(a.StartTime < b.EndTime) &&
(a.EndTime > b.StartTime)));
答案 1 :(得分:0)
这是一个非LINQ版本,它将使用集合按开始日期排序的事实:
List<Tuple<MachineryRecord,MachineryRecord>> OverlapingRecords(IEnumerable<MachineryRecord> sortedRecords)
{
var result = new List<Tuple<MachineryRecord, MachineryRecord>>();
MachineryRecord prev = null;
foreach (var current in sortedRecords)
{
if (prev != null)
{
if (current.StartTime < prev.EndTime) { result.Add(new Tuple<MachineryRecord, MachineryRecord>(prev,current)); }
}
prev = current;
}
return result;
}
我没有测试过它;)