从列表中查找最近的时间

所以,这是场景。 我有一个创建时间的文件,我想从文件创建时间最接近或相等的时间列表中选择一个时间……最好的方法是什么?

像这样的东西:

DateTime fileDate, closestDate; ArrayList theDates; long min = long.MaxValue; foreach (DateTime date in theDates) if (Math.Abs(date.Ticks - fileDate.Ticks) < min) { min = Math.Abs(date.Ticks - fileDate.Ticks); closestDate = date; } 
 var closestTime = listOfTimes.OrderBy(t => Math.Abs((t - fileCreateTime).Ticks)) .First(); 

如果您不想要OrderBy调用的性能开销,那么您可以使用类似于MinBy扩展方法:

 var closestTime = listOfTimes.MinBy(t => Math.Abs((t - fileCreateTime).Ticks)); 

接受的答案是完全错误的。 你想要的是这样的:

  DateTime fileDate, closestDate; List theDates; fileDate = DateTime.Today; //set to the file date theDates = new List(); //load the date list, obviously long min = Math.Abs(fileDate.Ticks - theDates[0].Ticks); long diff; foreach (DateTime date in theDates) { diff = Math.Abs(fileDate.Ticks - date.Ticks); if (diff < min) { min = diff; closestDate = date; } } 
 var closestTime = (from t in listOfTimes orderby (t - fileInfo.CreationTime).Duration() select t).First(); 

你多久会用同样的时间表做这件事? 如果您只进行一次,最快的方法可能就是扫描列表并跟踪您最近看到的时间。 当/如果你遇到更接近的时间,用更接近的时间替换“最接近的”。

如果你经常这样做,你可能想要对列表进行排序,然后使用二进制搜索。

获取文件creatime和列表中每次的差异,并对每个时间差的绝对值进行排序。 第一个应该是你正在寻找的答案。

使用文件时间与列表中的时间之间的最小绝对时间差。 你可能会得到两个相同的条目,然后你需要一个不同的方法来区分它们。

不是答案,而是关于上面提出的各种LINQ解决方案的问题。 LINQ效率如何? 我还没有用LINQ编写任何“真正的”程序,所以我不确定它的性能。

在此示例中,“listOfTimes”集合意味着我们已经迭代了一些基于文件系统的对象来收集时间。 在迭代期间而不是在LINQ中进行分析会更有效吗? 我认识到这些解决方案可能更“优雅”或很抽象的“数据库集合”理念,但我倾向于选择效率(必须是可读的)而不是优雅的编程。 只是想知道LINQ的成本是否会超过这里的优雅?

 var creationTimes = new [] {DateTime.Now.AddDays(-1), DateTime.Now.AddDays(-2)}; FileInfo fi = new FileInfo("C:/test.xml"); var closestTime = creationTimes .OrderBy(c => Math.Abs(c.Subtract(fi.CreationTime).Days)) .First(); 
 var min = listoftimes.Select( x => new { diff = Math.Abs((x - timeoffile).Ticks), time = x}). OrderBy(x => x.diff). First().time; 

注意:假设listoftimes中至少有一个条目。

我想我会更新这篇文章以包含一个真实世界的场景。 我想要这种function,因为我有一个博客,显示最新电影放映的新闻。

但是我不想在过去列出筛选(即筛选日期超过当前日期),因为我想显示一条记录,我需要通过某种ID来获取记录。

我已经离开了,如果简单,那么你可以按照这个过程,毫无疑问,LINQ等人的效率更高。

首先是模型

  public class LatestScreeeningsModel { public int Id { get; set; } public DateTime Date { get; set; } } 

然后是您可以从控制器调用的代码块

  private static LatestScreeeningsModel GetLatestScreening(IPublishedContent currentNode) { LatestScreeeningsModel latestScreening = new LatestScreeeningsModel(); DateTime fileDate; // get a list of screenings that have not shown yet var screenings = currentNode.AncestorsOrSelf("siteLanguage") .FirstOrDefault().Descendants("screening") .Select(x => new LatestScreeeningsModel() { Id = x.Id, Date = x.GetPropertyValue("date") }) .Where(x => x.Date > DateTime.Now).ToList(); fileDate = DateTime.Today; long min = Math.Abs(fileDate.Ticks - screenings[0].Date.Ticks); long diff; foreach (var comingDate in screenings) { diff = Math.Abs(fileDate.Ticks - comingDate.Date.Ticks); if (diff <= min) { min = diff; latestScreening = comingDate; } } return latestScreening; } 

我使用Umbraco来获取日期项目,但它适用于任何自定义模型,List等。

希望能帮助到你