Есть массив объектов класса A
.
class A
{
pubic double value;
}
Как с помощью LINQ найти элемент с минимальным значением value, а не само это значение, как произошло бы в случае arr.Min(a => a.value)
?
Не встречал конструкции, которая выполняла бы это действие за один Linq-запрос. А за два сделать довольно просто:
double min = arr.Min(a => a.value);
var result = arr.FirstOrDefault(a => a.Value == min);
2 вариант: Реализовать в Вашем классе интерфейс IComparable<T>
:
class A : IComparable<A>
{
public double value;
public int CompareTo(A other)
{
return value.CompareTo(other.value);
}
}
Тогда метод Min()
можно вызвать так, и он вернёт объект класса A с минимальным значением поля value
:
var result = arr.Min();
С помощью Linq это возможно, но неэффективно. Более простым решением будет написать соответствующий метод; к примеру так:
public static TItem MinByKey<TItem, TKey>(
this IEnumerable<TItem> items, Func<TItem, TKey> keySelector)
{
var comparer = Comparer<TKey>.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);
Раз уж мы подняли этот вопрос: самый простой метод — не строить собственный велосипед, а использовать готовое решение. Например, можно установить пакет MoreLinq
через nuget и использовать просто
using MoreLinq;
A best = arr.MinBy(a => a.value);
a.OrderBy(e => e.value).First();
В один короткий запрос, но это не эффективно.
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
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть задача, сделать выборку в таблице по возрасту - до ЛЕТДата рождения хранится в типе поля date
Как сделать автоматическую смену внешнего ключа в таблице при удалении родительской записи в другой таблице?