F # имеет удобные операторы minBy
и maxBy
, которые я хотел бы реализовать как методы расширения C #, поскольку библиотека Linq их опускает.Это немного работы, но только немного, и это позволяет вам избегать сложных выражений, таких как
var earliest = booList.First(b => b.Field3 == booList.Min(e => e.Field3));
Вместо этого вы можете ввести следующее:
var earliest = booList.MinBy(b => b.Field3);
Простая реализация:
static T MinBy<T, C>(this IEnumerable<T> sequence, Func<T, C> keySelector)
{
bool first = true;
T result = default(T);
C minKey = default(C);
IComparer<C> comparer = Comparer<C>.Default; //or you can pass this in as a parameter
foreach (var item in sequence)
{
if (first)
{
result = item;
minKey = keySelector.Invoke(item);
first = false;
continue;
}
C key = keySelector.Invoke(item);
if (comparer.Compare(key, minKey) < 0)
{
result = item;
minKey = key;
}
}
return result;
}
Это также несколько более эффективно, чем сложное выражение в верхней части, поскольку MinBy выполняет итерацию последовательности ровно один раз, в то время как выражение выполняет итерацию более одного раза и меньше или равно двум.И, конечно же, для сортировки и последующего выбора первого элемента требуется сортировка, то есть O (n log n), а это всего лишь O (n).