首页 > 解决方案 > 使用 LINQ 在列表中查找句点关系

问题描述

我有一个类,其中包含有关期间、开始和结束的日期信息:

public class A
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}

然后我有一个对象列表 A 在其中声明了几个句点:

List<A> listOfA = new List<A>()
{
     new A {Id=1,Name="1", Start = new DateTime (2020,1,1), End = new DateTime(2020,1,20) },
     new A {Id=2,Name="2", Start = new DateTime (2020,1,21), End = new DateTime(2020,2,20) },
     new A {Id=3,Name="3", Start = new DateTime (2020,5,11), End = new DateTime(2020,5,14) },
     new A {Id=4,Name="4", Start = new DateTime (2020,5,15), End = new DateTime(2020,5,20) }
};

我想在列表中的给定周期和周期之间找到关系(重叠、包含等):

var wrong = new A { Id = 5, Name = "5", Start = new DateTime(2020, 1, 3), End = new DateTime(2020, 4, 20) };
var ok = new A { Id = 6, Name = "6", Start = new DateTime(2020, 4, 3), End = new DateTime(2020, 4, 14) };

在上面的示例中,错误对象的开始日期在列表中的一个对象内,而 ok 对象没有关系。如何使用 LINQ 找到这种关系?

标签: c#asp.netlinq

解决方案


它是二次时间复杂度并且完全未经测试,但是它看起来不错,这才是最重要的

var results = list.Where(x => 
                    list.Any(y =>
                         x != y && 
                         (x.Start >= y.Start && x.Start <= y.End ||
                         x.End <= y.End && x.End >= y.Start)))
                  .ToList();

或者

给定

public class A
{
     public int Id { get; set; }
     public string Name { get; set; }
     public DateTime Start { get; set; }
     public DateTime End { get; set; }

     public bool Intersect(A a)
        => this != a && (Start >= a.Start && a.Start <= a.End || End <= a.End && End >= a.Start);
}

用法

var wrong = list.Where(x => list.Any(x.Intersect)).ToList();
var good = list.Except(wrong).ToList();

推荐阅读