74 lines
2.6 KiB (Stored with Git LFS)
C#
74 lines
2.6 KiB (Stored with Git LFS)
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Superlazy
|
|
{
|
|
public static class SLLinqUtil
|
|
{
|
|
public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
|
|
{
|
|
return source.MinBy(selector, null);
|
|
}
|
|
|
|
public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IComparer<TKey> comparer)
|
|
{
|
|
if (source == null) throw new ArgumentNullException("source");
|
|
if (selector == null) throw new ArgumentNullException("selector");
|
|
if (comparer == null) comparer = Comparer<TKey>.Default;
|
|
|
|
using var sourceIterator = source.GetEnumerator();
|
|
if (!sourceIterator.MoveNext())
|
|
{
|
|
throw new InvalidOperationException("Sequence contains no elements");
|
|
}
|
|
|
|
var min = sourceIterator.Current;
|
|
var minKey = selector(min);
|
|
while (sourceIterator.MoveNext())
|
|
{
|
|
var candidate = sourceIterator.Current;
|
|
var candidateProjected = selector(candidate);
|
|
if (comparer.Compare(candidateProjected, minKey) < 0)
|
|
{
|
|
min = candidate;
|
|
minKey = candidateProjected;
|
|
}
|
|
}
|
|
|
|
return min;
|
|
}
|
|
|
|
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
|
|
{
|
|
return source.MaxBy(selector, null);
|
|
}
|
|
|
|
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IComparer<TKey> comparer)
|
|
{
|
|
if (source == null) throw new ArgumentNullException("source");
|
|
if (selector == null) throw new ArgumentNullException("selector");
|
|
if (comparer == null) comparer = Comparer<TKey>.Default;
|
|
|
|
using var sourceIterator = source.GetEnumerator();
|
|
if (!sourceIterator.MoveNext())
|
|
{
|
|
throw new InvalidOperationException("Sequence contains no elements");
|
|
}
|
|
|
|
var max = sourceIterator.Current;
|
|
var maxKey = selector(max);
|
|
while (sourceIterator.MoveNext())
|
|
{
|
|
var candidate = sourceIterator.Current;
|
|
var candidateProjected = selector(candidate);
|
|
if (comparer.Compare(candidateProjected, maxKey) > 0)
|
|
{
|
|
max = candidate;
|
|
maxKey = candidateProjected;
|
|
}
|
|
}
|
|
|
|
return max;
|
|
}
|
|
}
|
|
} |