I would like to get ALL elements in enumerable whose property is the maximum :
IEnumerable<Person> allOldest = people.GroupBy(p => p.Age) .OrderByDescending(i=>i.Key).First().Select(_=>_);
.NET 6 introduce MaxBy
which return THE max item:
Person uniqueOldest = people.MaxBy(person => person.Age);
MaxBy
can't help me ? Is there another more elegant solution than first example?
3 Answers
Using Max
is a simple plain way of doing this:
var maxAge = items.Max(y => y.Age); var maxItems = items.Where(x => x.Age == maxAge);
5If you are OK with adding an external dependency to your project, you could install the respectable MoreLinq package (originally developed by the one and only Jon Skeet) and do this:
IEnumerable<Person> allOldest = MoreLinq.MoreEnumerable.MaxBy(people, p => p.Age);
The signature of the MoreEnumerable.MaxBy
method:
public static IExtremaEnumerable<TSource> MaxBy<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> selector);
You could also try to use it as an extension method, by adding this using
directive at the top:
using static MoreLinq.Extensions.MaxByExtension;
...but in .NET 6 this will result (most likely) in a name resolution conflict.
This is one of those times that linq isn't necessarily the best option. You could create a linq style extension to do it but really the most direct solution is just to write a function. Here's a simple example. I've used a value tuple as a stand in for your person object.
static void Main(string[] _) { var source = new (int key, int value)[] { (0, 0), (1, 5), (2, 1), (3, 5), (4, 0), (5, 5) }; var allMax = new List<(int, int)>(); int currentMax = int.MinValue; foreach (var (key, value) in source) { if (currentMax < value) { allMax.Clear(); allMax.Add((key, value)); currentMax = value; } else if (currentMax == value) { allMax.Add((key, value)); } } Console.WriteLine($"{allMax.Count} Max valued items found"); foreach (var (key, value) in allMax) Console.WriteLine($"({key}, {value})"); }
ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJobXJwZmh%2BdX2OpaCnqV2irrmu2GauoqyYYq6tuIyeo56llaPBtA%3D%3D