从列表中查找最接近的时间

时间:2009-11-18 16:13:42

标签: c# comparison

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

11 个答案:

答案 0 :(得分:46)

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

如果您不想要OrderBy来电的性能开销,那么您可以使用MinBy中的MoreLINQ扩展方法代替:

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

答案 1 :(得分:8)

这样的事情:

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;
 }

答案 2 :(得分:8)

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

  DateTime fileDate, closestDate;
  List<DateTime> theDates;

  fileDate = DateTime.Today;       //set to the file date
  theDates = new List<DateTime>(); //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;
    }
  }

答案 3 :(得分:6)

var closestTime = (from t in listOfTimes
                   orderby (t - fileInfo.CreationTime).Duration()
                   select t).First();

答案 4 :(得分:5)

您多久会使用相同的时间列表执行此操作?如果您只进行一次,最快的方法可能就是扫描列表并跟踪您最近看到的时间。当/如果您遇到更接近的时间,请将“最接近的”替换为更近的时间。

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

答案 5 :(得分:2)

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

答案 6 :(得分:1)

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

答案 7 :(得分:1)

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

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

答案 8 :(得分:0)

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();

答案 9 :(得分:0)

var min = listoftimes.Select(
    x => new { diff = Math.Abs((x - timeoffile).Ticks), time = x}).
    OrderBy(x => x.diff).
    First().time;

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

答案 10 :(得分:0)

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

但是我不想在过去列出筛选(即筛选日期超过当前日期),因为我想要显示一条记录,我需要通过某种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<DateTime>("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等人。

希望有所帮助