Страницы

Поиск по вопросам

четверг, 12 декабря 2019 г.

Как с помощью LINQ найти элемент с минимальным значением поля, а не само это значение?

#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

Комментариев нет:

Отправить комментарий