如何根据O(n)中使用LINQ的特定顺序找到第一个项目?
假设我有一个项目列表(例如,帖子),并且我想根据一些非平凡的顺序(例如,PublishDate然后评论计数作为决胜因子)找到第一个项目。 用LINQ做这件事的自然方式是这样的:
posts.OrderBy(post => post.PublishDate).ThenBy(post => post.CommentsCount).First()
然而,我的微优化器担心的是,调用OrderBy实际上花费我O(n * lgn)来排序整个列表,当我真正需要的是O(n)find-minimum操作时。
那么,LINQ智能够从OrderBy()返回什么知道如何优化随后的First()调用? 如果没有,那么开箱即用的更好方法是什么? (我总是可以编写我自己的FindMinimumItem实现,但看起来像是矫枉过正)。
排序很聪明,它只会对OrderBy
的第一个组执行ThenBy
,但OrderBy
仍然必须对所有项目进行排序,然后才能返回第一个组。
根据自定义比较,您可以使用Aggregate方法获取第一篇文章:
Post lowest =
posts.Aggregate((Post)null,
(x, y) =>
x == null
|| y.PublishDate < x.PublishDate
|| (y.PublishDate == x.PublishDate && y.CommentsCount < x.CommentsCount)
? y : x
);
(假设你正在使用LINQ to Objects。)
这是SQL还是LINQ to Objects? 如果是后者,你可能需要MinBy
的MinBy; 您的书面陈述确实会排序,然后采取第一项。
是的,它不包括这个(和类似的东西,如DistinctBy
)开箱即可。
编辑:我看到你的问题现在已经改变; MoreLINQ不支持这样的复合比较。 在MiscUtil中,我有创建一个IComparer<T>
- 您可以使用身份函数作为密钥选择器将其传入MinBy
。 随意为MinBy
添加一个功能请求,该功能需要一个源代码和一个没有密钥选择器的IComparer<T>
:)
通常这是一个max
或min
(我不知道它是如何在LinQ中调用的),给定一个特定的关键字; 排序和获得第一个或最后一个似乎在任何语言或框架矫枉过正。
上一篇: How to find the first item according to a specific ordering using LINQ in O(n)?