3

我有一个通用的项目清单。每个项目都包含一个 DateTime 字段。我想以最优雅和最有效的方式使用 Linq 找到列表中的最新项目。

就我而言,优雅比效率更重要,但以一种有效的方式这样做会很好。

谢谢你。

阅读答案后:这是代码(以及我喜欢的答案):

using System.Collections.Generic;
using System.Linq;

class Item
{
    public Item Date { get; set; }
    public string Name { get; set; }
}

static void Main(string[] args)
{
    List<Item> items = CreateItems();
    Item newest;
    if (items.Count == 0)
        newest = null;
    else
        newest = items.OrderByDescending(item => item.Date).First();
}
4

5 回答 5

7

为了优雅,我会根据日期时间字段对集合进行排序并返回第一项,例如:

set.OrderByDescending(x => x.DateTime)
   .FirstOrDefault();

这将创建已排序集合的内存表示,因此效率不是那么好。对于未排序的集合,最有效的解决方案是遍历所有项目并保存最新的。您可以通过执行聚合操作来使用 linq,我发现它在语法上是一团糟。

或者,您可以将项目存储在排序集合中,如 SortedSet。对于大多数集合,这具有更复杂的插入时间 0(log2) 而不是 O(1),但它允许您立即按日期时间排序,因此选择 O(1) 而不是 O(n) 中的最新项目。

于 2012-05-30T05:40:04.387 回答
7

到目前为止,大多数解决方案都必须首先对列表进行完全排序(通过 OrderByDescending),这是不必要且耗时的。你想要的是 Jon Skeet 的MoreLinq MaxBy函数。MaxBy 的来源在谷歌代码上。

var newest = thelist.MaxBy(x => x.DateTimeField);
于 2012-05-30T05:55:44.720 回答
3

试试看:

var newItem = myList.OrderByDescending(item => item.yourDateTimeField).First();
于 2012-05-30T05:26:09.197 回答
0

尝试聚合,例如:

list.Aggregate (
    DateTime.MinValue,
    (lastOne, current) => current.GreaterThan (lastOne) ? current : lastOne
)

即如果你的字段是 DateTimeField,你应该写类似

list.Aggregate (
    null,
    (lastOne, current) => 
        (lastOne == null) ||
             current.DateTimeField.GreaterThan (lastOne.DateTimeField)
        ? current
        : lastOne
)
于 2012-05-30T05:25:53.843 回答
0

试试这个

 sortlist.OrderByDescending(a => a.timeStamp).First();
于 2012-05-30T05:47:03.210 回答