I want to find, let's say, the minimum element in the list by field, but without cycles. LINQ Min does not return to me an object from the collection, but a field type, which is logical (NO!).

In c ++ there are functions that allow you to pass a function by which to make a comparison, and will return a collection object, which is logical (YES!).

Example:

class A { public int x; public int y; } ... List<A> list = new List<A>(); ... //можно так int min = int.MaxValue; A res; foreach(var it in list) { if( it.x < min ) { min = it.x; res = it; } } //или так(наверно, не проверял) но тут как бы уже два прохода по циклу. int min1 = list.Min(it => it.x); A res1 = list.Where(it => it.x == min1).First(); 

Is there something like this in C #? External tools cannot be connected.

Thank!

    3 answers 3

    There are several ways.

    • Implement the IComparable interface:

       class A : IComparable<A> { public int x; public int y; public int CompareTo(A other) { return this.x.CompareTo(other.x); } } 

      Now you can simply call the Min() method:

       A min = list.Min(); 
    • Use the Aggregate method.

       A min = list.Aggregate((a, b) => ax < bx ? a : b); 

      A very curious way, but non-intuitive. When looking at this design is not easy to understand what it does.

      It is possible in every way.

      For example:

       list.OrderBy(a => ax).First() 

      Or you can install MoreLinq from nuget , and just write

       using MoreLinq; 
       list.MinBy(a => ax) 

      Well, if the reluctance to connect other people's libraries, not for long and to write:

       public static class EnumerableExtensions { public static T MinBy<T>(this IEnumerable<T> source, Func<T, double> fun) { T result = default(T); double currmin = double.PositiveInfinity; bool first = true; foreach (var t in source) { double candidate = fun(t); if (first || candidate < currmin) { result = t; currmin = candidate; first = false; } } if (first) throw new ArgumentException("empty sequence at MinBy"); return result; } } 

        For information:

        No cycles can be written at all. LINQ to Objects behind the scenes is called the same ForEach and goes through all the elements of the collection, as if you explicitly used loops.

        Another thing is that everything is more concise ...

        • one
          For LINQ-to-objects you are right, but for LINQ-to-database the query goes to the database. - VladD