# Developers Planet

Mark Johnson February 2016

### Removing Overlapping Dates in LINQ

I have a really ghetto implementation of this, but I imagine there is some clean way to do this with Linq. I have a list of objects with a start and stop date.

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

In some cases there is no start date, its null. What I want the algorithm to do is remove items from the list until there is no overlapping of dates; I'm just using years to illustrate the concept:

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

Running this list through the algo should yield:

``````var y = Do(x);

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

There is the possibilities for cycles where, where there are different optimal solutions. My data doesn't have these edge cases.

tparnell February 2016

If your class Thing implements `IEquatable<Thing>` and you properly fill out the Equals, and GetHashCode methods you can then just do

var results = x.Distinct();

Enigmativity February 2016

I think this should work for you:

``````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)))
{
}
return a;
});
``````

This gives me: