简体   繁体   中英

Selecting according to a Min or Max on one value in LINQ

This is equivalent to a correlated subquery, where you want the row which has the biggest or smallest X (and not the biggest or smallest X itself). I've only been able to get it through sorting and picking the first item.

public static TSource PickMin<TSource, TMin>(this IEnumerable<TSource> source, Func<TSource, TMin> selector) where TMin : IComparable<TMin>
{
    return source.OrderBy(selector).FirstOrDefault();
}

Which doesn't exactly sound like the most efficient approach. I think there's a combination of .Contains and .Min which could accomplish this? Or is this as good as LINQ gets?

You can use aggregation, which is O(n) (and which is afair used behind the scene, when you call Min() , Max() , etc.):

public static TSource PickMin<TSource, TMin>(this IEnumerable<TSource> source, Func<TSource, TMin> selector) where TMin : IComparable<TMin>
{
     var first = source.FirstOrDefault();
     return source.Aggregate(first, (min, current) => selector(current).CompareTo(selector(min)) < 0 ? current : min);
}

If you want it to throw exceptions on empty collections (instead of returning a default value), remove the first line.

There is no good way to do this directly in LINQ. What you could is to use MinBy() from MoreLINQ

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM