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?
CodePudding user response:
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);
CodePudding user response:
If 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.
CodePudding user response:
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})");
}