从通用列表中选择与偏移分钟连接的项目的最佳/最快方法
本文关键字:项目 连接 最佳 方法 分钟 列表 选择 | 更新日期: 2023-09-27 18:31:27
我有一个包含StartTime和EndTime的对象列表。
我想选择在给定日期开始的所有项目,以及所有与结束时间给出的分钟数"连接"的项目。不应该有任何重叠的时间,因为我之前已经检查过了。
F.e. 类
public class tObject
{
public int ID { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
因此,如果我有具有这些开始和结束时间的tObject:
ID = 1 StartTime = 21.1.2016 21:00 - EndTime = 22.1.2016 01:00
ID = 2 StartTime = 22.1.2016 01:30 - EndTime = 22.1.2016 05:00
ID = 3 StartTime = 22.1.2016 06:00 - EndTime = 22.1.2016 07:00
ID = 4 StartTime = 22.1.2016 07:50 - EndTime = 22.1.2016 08:00
ID = 5 StartTime = 22.1.2016 09:10 - EndTime = 22.1.2016 11:00
如何从列表项中进行选择,同时选择 2,3,4 ID:s(连接 60 分钟偏移量)以列出今日项目?
int iMinutes = 60;
List<tObject> listTodaysItems = listItems.Where(r => r.StartTime.Date == dtGivenDate.Date).ToList();
我知道这可以用 for -loop 来做,但我必须经常这样做,所以如果可能的话,我会更喜欢单行选择。还想知道是否可以以某种方式检查同一列表中的其他值。
那么我在这里最好/最快的选择是什么?
如果我理解正确,您需要以下内容:
int threshold = 20;
var withinThreshold =
list.Where(x => list.Where(y => y.StartTime < x.StartTime && y.EndTime.AddMinutes(threshold) > x.StartTime)
.Any())
.Select(x => x).ToList();
这将查看在当前条目之前开始的每个条目,并检查当前条目是否在任何一个条目的阈值范围内。
这里有一些带有测试数据的完整示例程序,随时可用:
using System;
using System.Linq;
using System.Collections.Generic;
public class TObject
{
public int ID { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Program
{
public static void Main()
{
List<TObject> list = new List<TObject>();
for(int i = 0; i < 100; i++)
{
list.Add(new TObject());
list[i].StartTime = (i == 0 ? DateTime.Now : list[i-1].EndTime.AddMinutes(i + 1));
list[i].EndTime = list[i].StartTime.AddMinutes(i);
Console.WriteLine(list[i].StartTime + " - " + list[i].EndTime);
}
int threshold = 20;
var withinThreshold =
list.TakeWhile( // Stop as soon as the an entry does not match the condition
x =>
!list.Where(y => y.StartTime < x.StartTime).Any() || // First entry
list.Where(y => y.StartTime < x.StartTime && y.EndTime.AddMinutes(threshold) > x.StartTime).Any()) // Following entries withing threshold
.Select(x => x)
.ToList();
Console.WriteLine("Within threshold: ");
withinThreshold.ForEach(x => Console.WriteLine(x.StartTime + " - " + x.EndTime));
}
}