#c_sharp #net #linq
Есть массив объектов класса A. class A { pubic double value; } Как с помощью LINQ найти элемент с минимальным значением value, а не само это значение, как произошло бы в случае arr.Min(a => a.value)?
Ответы
Ответ 1
Не встречал конструкции, которая выполняла бы это действие за один Linq-запрос. А за два сделать довольно просто: double min = arr.Min(a => a.value); var result = arr.FirstOrDefault(a => a.Value == min); 2 вариант: Реализовать в Вашем классе интерфейс IComparable: class A : IComparable { public double value; public int CompareTo(A other) { return value.CompareTo(other.value); } } Тогда метод Min() можно вызвать так, и он вернёт объект класса A с минимальным значением поля value: var result = arr.Min(); Ответ 2
С помощью Linq это возможно, но неэффективно. Более простым решением будет написать соответствующий метод; к примеру так: public static TItem MinByKey( this IEnumerable items, Func keySelector) { var comparer = Comparer .Default; var enumerator = items.GetEnumerator(); if (!enumerator.MoveNext()) throw new InvalidOperationException("Collection is empty."); TItem minItem = enumerator.Current; TKey minKey = keySelector(minItem); while (enumerator.MoveNext()) { TKey key = keySelector(enumerator.Current); if (comparer.Compare(key, minKey) < 0) { minItem = enumerator.Current; minKey = key; } } return minItem; } Тогда задача сведётся к вызову arr.MinByKey(a => a.value); Ответ 3
Раз уж мы подняли этот вопрос: самый простой метод — не строить собственный велосипед, а использовать готовое решение. Например, можно установить пакет MoreLinq через nuget и использовать просто using MoreLinq; A best = arr.MinBy(a => a.value);Ответ 4
a.OrderBy(e => e.value).First(); В один короткий запрос, но это не эффективно.Ответ 5
var a = array.Aggregate((r, x) => r.Value < x.Value ? r : x); Код полностью: https://ideone.com/80oSKs using System; using System.Linq; class A { public double Value; public static implicit operator A(double x) { return new A() { Value = x }; } } public class Test { public static void Main() { var array = new A[] { 1.7, 2.3, -7.8, -11.1, 4.5, 42 }; var a = array.Aggregate((r, x) => r.Value < x.Value ? r : x); Console.WriteLine(a.Value); Console.WriteLine(Object.ReferenceEquals(a, array[3])); } } Результат: -11.1 True
Комментариев нет:
Отправить комментарий