There is an array of objects of class A
class A { pubic double value; } How to use LINQ to find an element with the minimum value value, and not the value itself, as would happen in the case of arr.Min(a => a.value) ?
Did not meet a construction which would execute this action for one Linq request. And for two to do is quite simple:
double min = arr.Min(a => a.value); var result = arr.FirstOrDefault(a => a.Value == min); Option 2: Implement the IComparable<T> interface in your class:
class A : IComparable<A> { public double value; public int CompareTo(A other) { return value.CompareTo(other.value); } } Then the Min() method can be called like this, and it returns an object of class A with the minimum value of the value field:
var result = arr.Min(); Aggregate :) - Qwertiy ♦With Linq, this is possible, but inefficient. A simpler solution would be to write the appropriate method; for example:
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; } Then the task will be reduced to a challenge.
arr.MinByKey(a => a.value); (элемент, индекс) , then finding the minimum and extracting the index from the tuple is one pass, but you need to create tuples. If the type of the tuple is significant (Value type), then this option, in principle, is optimal, otherwise there will be an additional memory allocation. - AlexeyM var a = array.Aggregate((r, x) => r.Value < x.Value ? r : x); Complete code: 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])); } } Result:
-11.1 True a.OrderBy(e => e.value).First(); In one short request, but it is not efficient.
Since we raised this question: the simplest method is not to build your own bicycle, but to use a ready-made solution. For example, you can install the MoreLinq package via nuget and use just
using MoreLinq; A best = arr.MinBy(a => a.value); Source: https://ru.stackoverflow.com/questions/87343/
All Articles