LINQ查询 - 最近的相邻日期

Ste*_*bbi 6 .net c# 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;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 20

那么,使用MinByMoreLINQ:

var nearest = dateSet.MinBy(date => Math.Abs((date - targetDate).Ticks);
Run Code Online (Sandbox Code Playgroud)

换句话说,对于每一日期,发现它有多远从其他(或者反过来)减去一个日期,服用的数量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();
Run Code Online (Sandbox Code Playgroud)

  • 如果没有MoreLINQ,相同的算法可以与其他一些LINQ表达式一起使用:`return dateSet.OrderBy(date => Math.Abs​​((date - targetDate).Ticks).First();` (10认同)
  • @esker:那样做 - 但它需要O(N)内存和O(N log N)时间,而不是O(1)内存和O(N)时间.它基本上不优雅,IMO :)但是,它可能就是所有需要的...... (2认同)