LINQ查询 - 最近的相邻日期

时间:2011-08-10 19:27:50

标签: c# .net linq

我正在尝试编写一个方法,在给定日期列表和目标日期的情况下,按时间顺序确定最接近的日期。例如,给定(2011年1月,2011年3月,2011年11月)的(简化)日期集,以及2011年4月的目标日期,该方法将返回2011年3月

起初,我正在考虑使用LINQ的跳过,但我不确定是否有合适的Func,以便在超过日期之前停止。下面这似乎是一个可行的解决方案,但我不确定是否有更有效的方法来做到这一点。据推测,Last和First各自都是线性时间。

源数据集可以在0到10,000个日期之间,通常大约为5,000。此外,我在整个过程中迭代5到50次(这是不同迭代的目标日期数)。

// assume dateSet are ordered ascending in time.
public DateTime GetClosestDate(IEnumerable<DateTime> dateSet, DateTime targetDate)
{
   var earlierDate = dateSet.Last(x => x <= targetDate);
   var laterDate = dateSet.First(x => x >= targetDate);

   // compare TimeSpans from earlier to target and later to target.
   // return closestTime;
}

2 个答案:

答案 0 :(得分:19)

好吧,使用MinBy中的MoreLINQ

var nearest = dateSet.MinBy(date => Math.Abs((date - targetDate).Ticks);

换句话说,对于每个日期,通过从另一个日期中减去一个日期(无论是哪一方向),在结果Ticks中取TimeSpan的数量,然后查找,找出它的距离绝对值。选择给出该差异的最小结果的日期。

如果你不能使用MoreLINQ,你可以自己写一些类似的东西,或者分两步完成(blech):

var nearestDiff = dateSet.Min(date => Math.Abs((date - targetDate).Ticks));
var nearest = dateSet.Where(date => Math.Abs((date - targetDate).Ticks) == nearestDiff).First();

答案 1 :(得分:1)

使用Last和First迭代dateSet两次。您可以使用自己的逻辑自己迭代dateSet。这样会更有效,但除非你的dateSet非常大或枚举dateSet由于某些其他原因而非常昂贵,速度的微小提升可能不值得编写更复杂的代码。您的代码应该首先易于理解。