我有一个真正的贫民窟实现这个,但我想有一些干净的方式与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}
}
在存在不同最优解的情况下,存在循环的可能性。我的数据没有这些边缘情况。
答案 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;
});
这给了我:
答案 1 :(得分:-2)
如果您的类Thing实现了IEquatable<Thing>
并且您正确地填写了Equals和GetHashCode方法,那么您可以这样做
var results = x.Distinct();