In case you don't want to use MoreLINQ and want to get linear time, you can also use Aggregate
:
var maxItem =
items.Aggregate(
new { Max = Int32.MinValue, Item = (Item)null },
(state, el) => (el.ID > state.Max)
? new { Max = el.ID, Item = el } : state).Item;
This remembers the current maximal element (Item
) and the current maximal value (Item
) in an anonymous type. Then you just pick the Item
property. This is indeed a bit ugly and you could wrap it into MaxBy
extension method to get the same thing as with MoreLINQ:
public static T MaxBy(this IEnumerable<T> items, Func<T, int> f) {
return items.Aggregate(
new { Max = Int32.MinValue, Item = default(T) },
(state, el) => {
var current = f(el.ID);
if (current > state.Max)
return new { Max = current, Item = el };
else
return state;
}).Item;
}