我有一个通用的项目清单。每个项目都包含一个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();
}
答案 0 :(得分:7)
为了优雅,我会根据日期时间字段对集合进行排序并返回第一个项目,如:
set.OrderByDescending(x => x.DateTime)
.FirstOrDefault();
这将创建已排序集合的内存中表示,因此效率不高。对于未排序的集合,最有效的解决方案是循环所有项目并保存最新的。您可以通过执行聚合操作来使用linq,我发现在语法上一团糟。
或者,您可以将项目存储在SortedSet等已排序的集合中。对于大多数集合,这有一个更复杂的插入时间0(log2)而不是O(1),但它允许您对日期时间进行无差别排序,因此选择O(1)中的最新项而不是O(n)。
答案 1 :(得分:6)
到目前为止,大多数解决方案必须首先对列表进行完全排序(通过OrderByDescending),这是不必要且耗时的。你想要的是Jon Skeet的MoreLinq MaxBy
功能。 MaxBy的来源是google code。
var newest = thelist.MaxBy(x => x.DateTimeField);
答案 2 :(得分:3)
试试:
var newItem = myList.OrderByDescending(item => item.yourDateTimeField).First();
答案 3 :(得分:0)
尝试使用Aggregate,例如:
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
)
答案 4 :(得分:0)
尝试这个
sortlist.OrderByDescending(a => a.timeStamp).First();