Linq MaxBy 与所有元素?
Posted
技术标签:
【中文标题】Linq MaxBy 与所有元素?【英文标题】:Linq MaxBy with all elements? 【发布时间】:2021-11-06 10:23:12 【问题描述】:我想获取属性最大的可枚举的所有元素:
IEnumerable<Person> allOldest = people.GroupBy(p => p.Age)
.OrderByDescending(i=>i.Key).First().Select(_=>_);
.NET 6 引入了MaxBy
,它返回最大项:
Person uniqueOldest = people.MaxBy(person => person.Age);
MaxBy
帮不了我?
还有比第一个例子更优雅的解决方案吗?
【问题讨论】:
只对输入进行一次迭代对您来说很重要吗?如果没有,您可以使用Max
获取最大值,然后使用Where
获取具有该值的所有元素。
谢谢乔恩。为什么不。但它是否比 1 次迭代更优化?我认为大枚举和很多次,如果适用的话,在 SQL 中进行 EF 转换
我不确定您所说的“比 1 次迭代更优化”是什么意思 - 如果您需要为 EF 提供此功能,请在问题中说明,因为它可能会产生许多其他答案不合适。
【参考方案1】:
使用Max
是一种简单明了的方式:
var maxAge = items.Max(y => y.Age);
var maxItems = items.Where(x => x.Age == maxAge);
【讨论】:
好的,但是 maxItems 是 IGroupingitems
两次的潜在问题。如果 items
是一个延迟枚举,连接到数据库或其他一些非内存数据源,这可能是一个问题。
@TheodorZoulias 甚至不是两次,而是items.Count() + 1
次,这要糟糕得多 =)
@GuruStron 你是对的。但是在 Ran Turner 的最新编辑之后,我最初的评论仍然成立。 ?【参考方案2】:
如果您可以在项目中添加外部依赖项,则可以安装受人尊敬的 MoreLinq 包(最初由唯一的 Jon Skeet 开发)并执行以下操作:
IEnumerable<Person> allOldest = MoreLinq.MoreEnumerable.MaxBy(people, p => p.Age);
MoreEnumerable.MaxBy
方法的签名:
public static IExtremaEnumerable<TSource> MaxBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> selector);
您也可以尝试将其用作扩展方法,在顶部添加此 using
指令:
using static MoreLinq.Extensions.MaxByExtension;
...但在 .NET 6 中,这将导致(很可能)名称解析冲突。
【讨论】:
【参考方案3】:这是 linq 不一定是最佳选择的时代之一。您可以创建一个 linq 样式扩展来执行此操作,但实际上最直接的解决方案就是编写一个函数。这是一个简单的例子。我已使用值元组代替您的 person 对象。
static void Main(string[] _)
var source = new (int key, int value)[] (0, 0), (1, 5), (2, 1), (3, 5), (4, 0), (5, 5) ;
var allMax = new List<(int, int)>();
int currentMax = int.MinValue;
foreach (var (key, value) in source)
if (currentMax < value)
allMax.Clear();
allMax.Add((key, value));
currentMax = value;
else if (currentMax == value)
allMax.Add((key, value));
Console.WriteLine($"allMax.Count Max valued items found");
foreach (var (key, value) in allMax)
Console.WriteLine($"(key, value)");
【讨论】:
以上是关于Linq MaxBy 与所有元素?的主要内容,如果未能解决你的问题,请参考以下文章