从通用列表中选择与偏移分钟连接的项目的最佳/最快方法

本文关键字:项目 连接 最佳 方法 分钟 列表 选择 | 更新日期: 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));
    }
}