0

How to get the Property ID 3 ? There is a way to cast result to Conta?

List<Conta> contas = new List<Conta>();

contas.Add(new Conta { ID = 1, Saldo = 30 });
contas.Add(new Conta { ID = 2, Saldo = 50 });
contas.Add(new Conta { ID = 3, Saldo = 100 });

var result = contas.Where(c => c.Saldo == contas.Max(l => l.Saldo)) ;
Helio Ferreira
  • 163
  • 1
  • 3
  • 11
  • Possible duplicate of [Better way to return an object by max() in LINQ](http://stackoverflow.com/questions/18766517/better-way-to-return-an-object-by-max-in-linq) –  Feb 25 '16 at 15:15
  • 1
    That's going to be O(N^2)... At the very least grab the max value outside the `Where()` – Matthew Watson Feb 25 '16 at 15:19

4 Answers4

2
var max = Users.OrderByDescending(x => x.Saldo).FirstOrDefault();
Souhaieb Besbes
  • 1,485
  • 17
  • 30
  • Simple, short, and sweet. I like it! I had recently gone down a road of writing some long-winded "Max" function, just to realize this is perfect. Thanks. – Kevin B Burns Sep 07 '21 at 15:16
1

Use Single() or First() if you only want one result:

var result = contas.FirstOrDefault(c => c.Saldo == contas.Max(l => l.Saldo));

This will returns the Conta object with maximum Saldo.

Arturo Menchaca
  • 15,783
  • 1
  • 29
  • 53
1

You want a MaxBy() extension method. These are widely available on NuGet.

Once you have that, the solution become simply:

List<Conta> contas = new List<Conta>();

contas.Add(new Conta { ID = 1, Saldo = 30 });
contas.Add(new Conta { ID = 2, Saldo = 50 });
contas.Add(new Conta { ID = 3, Saldo = 100 });

var result = contas.MaxBy(x => x.Saldo);

Console.WriteLine(result.ID);

Here's a sample implementation of MaxBy() (credits to Jon Skeet et al for this):

public static class EnumerableExt
{
    public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
    {
        return source.MaxBy(selector, Comparer<TKey>.Default);
    }

    public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IComparer<TKey> comparer)
    {
        using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
        {
            if (!sourceIterator.MoveNext())
            {
                throw new InvalidOperationException("Sequence was empty");
            }

            TSource max = sourceIterator.Current;
            TKey maxKey = selector(max);

            while (sourceIterator.MoveNext())
            {
                TSource candidate = sourceIterator.Current;
                TKey candidateProjected = selector(candidate);

                if (comparer.Compare(candidateProjected, maxKey) > 0)
                {
                    max = candidate;
                    maxKey = candidateProjected;
                }
            }

            return max;
        }
    }
}
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
0

Instead of using .Where() use Single() / SingleOrDefault() / First() / FirstOrDefault()

Single will throw an exception if there is 0 or more than 1 elements in the result.

SingleOrDefault will throw an exception if there is more than 1 element in the result.

First will throw if there are no results ( list is empty)

FirstOrDefault will throw if the list is null.