Reputation: 4484
If I have an
IEnumerable<Something>
and a function that takes a Something, and return an int, how would I use LINQ to tell me which of my somethings gives the highest result when fed to my function?
Upvotes: 2
Views: 184
Reputation: 4908
var something= List.Aggregate((p, q) => func(p) > func(q) ? p : q)
This aggregate is simple but call func method occured twice for max in per iteration, to avoid this:
var something=List.Select(p => new { something = p, call = func(p) })
.Aggregate((p, q) => p.call > q.call ? p : q).something;
Upvotes: 1
Reputation: 393613
You can use something like MaxBy
from MoreLinq
(or simply use MoreLinq):
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
throw new InvalidOperationException("Sequence was empty");
TSource max = sourceIterator.Current;
TKey maxKey = selector(max);
while (sourceIterator.MoveNext())
{
TSource candidate = sourceIterator.Current;
TKey candidateProjected = selector(candidate);
if (comparer.Compare(candidateProjected, maxKey) > 0)
{
max = candidate;
maxKey = candidateProjected;
}
}
return max;
}
}
Upvotes: 3
Reputation: 838896
You can use OrderByDescending
:
Something result = yourEnumerable.OrderByDescending(x => f(x)).First();
Note that this results in a O(n log n) sort if you are using LINQ to Objects.
You could also use MaxBy
from MoreLINQ:
Something result = yourEnumerable.MaxBy(x => f(x));
Upvotes: 2