Andrew White
Andrew White

Reputation: 1789

Linq: Grouping a list, sorting it and getting top x values?

I have a list:

Name  Country    Value
John  Ireland    100
Mary  UK         200
Peter Germany    300
Bob   UK         100
Pat   France     400

I need to Group the list by the country, then sort by the summed values DESC then take the top X values

e.g. List.TopX(3) would return

France  400
UK      300
Germany 300

Upvotes: 4

Views: 10023

Answers (2)

StriplingWarrior
StriplingWarrior

Reputation: 156524

I didn't have time to fully comment this when I answered it over the weekend, but I had a few things I wanted to say. First of all, I agree with commenters that this sounds an awful lot like homework. If you had tried something and were running into trouble, I would expect to hear where your trouble spot is. Stack Overflow is about professionals helping one another with specific problems when they have tried everything and can't quite get it right. This question has a trivial response (for anyone who has taken time to read a little about LINQ). I intentionally used chained lambda notation rather than a LINQ expression in order to point out how the response is really a direct translation of the question:

var results = list.GroupBy(e => e.Country) // group the list by country
    .OrderByDescending(                 // then sort by the summed values DESC
        g => g.Sum(e => e.Value))  
    .Take(n)                            // then take the top X values
    .Select(                            // e.g. List.TopX(3) would return...
        r => new {Country = r.Key, Sum = r.Sum(e => e.Value)}); 

If I were actually doing this for work, I would use the following notation:

var results = from e in list
              group e.Value by e.Country into g
              let sum = g.Sum()
              orderby sum descending
              select new {g.Key, sum};
results = results.Take(n);

Upvotes: 13

Ruben Bartelink
Ruben Bartelink

Reputation: 61795

var all = from item in list
group item by item.Country into byCountry
let count = byCountry.Sum(element=>element.Value)
orderby count descending
select byCountry.Key, count

var justTop = all.Take(3);

Not entered into a compiler, but that should be the easy bit - Donwload LINQPad, look at the LINQPad tutorials on http://dimecasts.net and you'll have it sorted :P

Upvotes: 3

Related Questions