3

What's the best way to do this with Linq?

I have a List that contain two properties: Number and Percentage.

Sometimes in the list there are duplicate Numbers:

 -----------------------------
 Number: 182 | Percentage: 15%
 Number: 182 | Percentage: 70%
 ...

When a duplicate Number is found, I'd like to select the object that has the lowest of the two percentage values and transfer these results into a new List.

proggrock
  • 3,239
  • 6
  • 36
  • 51

5 Answers5

4
var query = from x in list
            group x by x.Number into x
            select x.OrderBy(y => y.Percentage).First();
Aducci
  • 26,101
  • 8
  • 63
  • 67
4

Try the following

var list = originalList
    .GroupBy(x => x.Number)
    .Select(x => x.OrderBy(y => y.Percentage).First())
    .ToList();

This query will first group the items by the Number value. It will then order each group by the percentage and select out the first element (which is the lowest).

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
3

Would this work?

collection.GroupBy(item => item.Number).Select(group => group.Min())
hehewaffles
  • 582
  • 5
  • 17
1
  var query = (from l in lst
         group l by l.Number into g
         select g.Min(x => x.Percentage)).ToList();
ionden
  • 12,536
  • 1
  • 45
  • 37
1

Changing this up based on the interpretation that by "LINQ" the poster desires query-comprehension syntax instead of dot-syntax (otherwise the other responses suffice):

var query =
    from i in list
    group i by i.Number into gj
    select gj.OrderBy(x => x.Percentage).First();

But this still uses a lot of dot-syntax for the ordering. Which would be the functional equivalent of:

var query =
    from i in list
    group i by i.Number into gj
    select 
        (from i in gj
        orderby i.Percentage
        select i).First();

If you don't like the .First() call on the end, that's going to be a challenge that either will not have a solution within the LINQ language transforms or the solution you end up with will not be the clean solution that IMHO dot syntax provides for this problem. Query comprehensions can often make things simpler, but in this case I prefer the dot-syntax:

var query =
    list.GroupBy(i => i.Number)
        .Select(gj => gj.OrderBy(i => i.Percentage).First());

The gj.OrderBy(...).First() portion accomplishes a More-LINQ-style MinBy operation (See Jon Skeet's post)

Community
  • 1
  • 1
devgeezer
  • 4,159
  • 1
  • 20
  • 26