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(this IEnumerable source, Func propSelector) //{ // return source.OrderBy(propSelector).FirstOrDefault(); //} public static int FindIndexMinBy(this IEnumerable source, Func selector) { return source.FindIndexMinBy(selector, null); } public static int FindIndexMinBy(this IEnumerable source, Func selector, IComparer comparer) { if (source == null) throw new ArgumentNullException("source"); if (selector == null) throw new ArgumentNullException("selector"); comparer = comparer ?? Comparer.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(this IEnumerable source, Func selector) { return source.FindObjMinBy(selector, null); } public static TSource FindObjMinBy(this IEnumerable source, Func selector, IComparer comparer) { if (source == null) throw new ArgumentNullException("source"); if (selector == null) throw new ArgumentNullException("selector"); comparer = comparer ?? Comparer.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(this IEnumerable source, Func selector) { return source.FindObjMaxBy(selector, null); } public static TSource FindObjMaxBy(this IEnumerable source, Func selector, IComparer comparer) { if (source == null) throw new ArgumentNullException("source"); if (selector == null) throw new ArgumentNullException("selector"); comparer = comparer ?? Comparer.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; } } } }