This does the same as Enumerable.Max(), but allows for a second function to select the result, rather than returning the usually useless score.
public static U Max<T, U>(this IEnumerable<T> items, Func<T, double> scorer, Func<T, U> selector)
{
var firstTime = true;
var bestScore = 0.0;
var bestItem = default(T);
foreach (var i in items)
{
var score = scorer(i);
if (firstTime || score > bestScore)
{
firstTime = false;
bestItem = i;
bestScore = score;
}
}
return selector(bestItem);
}