Search code examples
c#linqmaxby

MaxBy() is there a way to get multiple max values?


I am trying to get the maximum values out of a list but if there are multiple max values then I want to get all the max values.

For instance I have: Name1, 31 Name2, 35 Name3, 33 Name4, 35

And I want to get: {Name2, 35} AND {Name4, 35}

I tried using MaxBy();

But that only returns the first item(Name2, 35). Any help will be greatly appreciated

struct Amounts
{
    public string Name;
    public int Total;
}

Amount highestAmount = amounts.MaxBy(x => x.Total);


Solution

  • You can do it by using GroupBy first then using MaxBy on each key. Here is an extension method:

    public static IEnumerable<TSource> MaxsBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
    {
        return source.GroupBy(keySelector).MaxBy(g => g.Key);
    }
    

    Here is a working demo:

    using System;
    using System.Linq;
    using System.Collections.Generic;
    
    public class Program
    {
        struct Amounts
        {
            public string Name;
            public int Total;
        }
    
        public static void Main()
        {
            var amounts = new List<Amounts>
            {
                new Amounts { Name = "Name1", Total = 31 },
                new Amounts { Name = "Name2", Total = 35 },
                new Amounts { Name = "Name3", Total = 32 },
                new Amounts { Name = "Name4", Total = 35 }
            };
            var results = amounts.MaxsBy(x => x.Total);
            Console.WriteLine(string.Join("\n", results.Select(x => x.Name)));
        }
    }
    
    public static class Extensions 
    {
        public static IEnumerable<TSource> MaxsBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
        {
            return source.GroupBy(keySelector).MaxBy(g => g.Key);
        }
    }
    

    output

    Name2
    Name4