我有一个class A { public float Score; ... }
和一个IEnumerable<A> items
,希望找到得分最低的A
。
使用items.Min(x => x.Score)
可获得最低分数,而不是得分最低的实例。
如何通过仅通过我的数据迭代来获取实例?
编辑:这么长时间有三个主要解决方案:
编写扩展方法(由Svish提出)。 优点:易于使用和评估每个项目只有一次得分。 缺点:需要扩展方法。 (我为我的申请选择了这个解决方案。)
使用Aggregate(由Daniel Renshaw提出)。 Pros :使用内置的LINQ方法。 缺点:对未经训练的眼睛略微混淆并多次调用评估者。
实施IComparable(由cyberzed提出)。 优点:可以直接使用Linq.Min。 缺点:固定为一个比较器 - 在执行最小计算时无法自由选择比较器。
答案 0 :(得分:63)
使用聚合:
items.Aggregate((c, d) => c.Score < d.Score ? c : d)
正如所建议的那样,完全相同的行以及更友好的名称:
items.Aggregate((minItem, nextItem) => minItem.Score < nextItem.Score ? minItem : nextItem)
答案 1 :(得分:19)
尝试items.OrderBy(s => s.Score).FirstOrDefault();
答案 2 :(得分:14)
查看MoreLINQ中的 MinBy 扩展方法(由Jon Skeet创建,现在主要由Atif Aziz维护)。
MinBy source code(它非常简单,并且不依赖于其他文件)。
答案 3 :(得分:7)
这可以通过一点点简单的迭代来解决:
float minScore = float.MaxValue;
A minItem = null;
foreach(A item in items)
{
if(item.Score < minScore)
minItem = item;
}
return minItem;
这不是一个很好的LINQ查询,但它确实避免了排序操作,只根据问题的要求迭代列表一次。
答案 4 :(得分:4)
我认为快速的方法是为你的A级实现IComparable(如果可能的话)
class A : IComparable<A>
这是一个简单的实现,您可以在其中编写CompareTo(A other)
,查看IEnumerable(of T).Min on MSDN以获取参考指南
答案 5 :(得分:3)
应该做一点点折叠:
var minItem = items.Aggregate((acc, c) => acc.Score < c.Score? acc : c);
啊......太慢了。
答案 6 :(得分:2)
items.OrderBy(s => s.Score).Take(1);
具有相同的效果。使用Take(5)取最低5等。