using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
|
namespace IStation
|
{
|
public static class LinqExtensions
|
{
|
//public static T MinBy<T, TProp>(this IEnumerable<T> source, Func<T, TProp> propSelector)
|
//{
|
// return source.OrderBy(propSelector).FirstOrDefault();
|
//}
|
|
public static int FindIndexMinBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
|
{
|
return source.FindIndexMinBy(selector, null);
|
}
|
public static int FindIndexMinBy<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");
|
comparer = comparer ?? Comparer<TKey>.Default;
|
int min_indx = 0;
|
using (var sourceIterator = source.GetEnumerator())
|
{
|
if (!sourceIterator.MoveNext())
|
{
|
throw new InvalidOperationException("Sequence contains no elements");
|
}
|
var min = sourceIterator.Current;
|
|
int indx = 0;
|
var minKey = selector(min);
|
while (sourceIterator.MoveNext())
|
{
|
indx++;
|
var candidate = sourceIterator.Current;
|
var candidateProjected = selector(candidate);
|
if (comparer.Compare(candidateProjected, minKey) < 0)
|
{
|
min_indx = indx;
|
min = candidate;
|
minKey = candidateProjected;
|
}
|
}
|
return min_indx;
|
}
|
}
|
public static TSource FindObjMinBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
|
{
|
return source.FindObjMinBy(selector, null);
|
}
|
|
public static TSource FindObjMinBy<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");
|
comparer = 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 FindObjMaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
|
{
|
return source.FindObjMaxBy(selector, null);
|
}
|
|
public static TSource FindObjMaxBy<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");
|
comparer = 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;
|
}
|
}
|
}
|
}
|