删除LINQ中的重叠日期

时间:2016-02-09 01:11:31

标签: c# linq

我有一个真正的贫民窟实现这个,但我想有一些干净的方式与Linq这样做。我有一个带有开始和结束日期的对象列表。

class Thing
{
  int ID;
  ...
  DateTime? StartDate;
  DateTime EndDate;
}

在某些情况下,没有开始日期,它为空。我希望算法做的是从列表中删除项目,直到日期没有重叠;我只用了几年来说明这个概念:

List<Thing> x = new List<Thing>()
{
  {1, 2012, 2014}
  {2, 2013, 2015}
  {3, 2014, 2016}
  {4, <null>, 2015}
  {5, 2016, 2017}
}

通过算法运行此列表应该产生:

var y = Do(x);

y =
{
  {1, 2012, 2014}
  {2, <null>, 2015}
  {3, 2016, 2017}
}

在存在不同最优解的情况下,存在循环的可能性。我的数据没有这些边缘情况。

2 个答案:

答案 0 :(得分:0)

我认为这应该适合你:

List<Thing> x = new List<Thing>()
{
    new Thing () { ID = 1, StartDate = new DateTime(2012, 1, 1), EndDate  = new DateTime(2014, 1, 1) },
    new Thing () { ID = 2, StartDate = new DateTime(2013, 1, 1), EndDate  = new DateTime(2015, 1, 1) },
    new Thing () { ID = 3, StartDate = new DateTime(2014, 1, 1), EndDate  = new DateTime(2016, 1, 1) },
    new Thing () { ID = 4, StartDate = null, EndDate  = new DateTime(2015, 1, 1) },
    new Thing () { ID = 5, StartDate = new DateTime(2016, 1, 1), EndDate  = new DateTime(2017, 1, 1) },
};

Func<Thing, Thing, bool> overlaps =
    (t0, t1) =>
        (t0.StartDate.HasValue ? t0.StartDate.Value <= t1.EndDate : false)
            && (t1.StartDate.HasValue ? t0.EndDate >= t1.StartDate : false);

var y = x.Skip(1).Aggregate(x.Take(1).ToList(), (a, b) =>
{
    if (a.All(c => !overlaps(b, c)))
    {
        a.Add(b);
    }
    return a;
});

这给了我:

y

答案 1 :(得分:-2)

如果您的类Thing实现了IEquatable<Thing>并且您正确地填写了Equals和GetHashCode方法,那么您可以这样做

var results = x.Distinct();