Using GroupBy and Max in LINQ Lambda Expressions
Solution 1
EDIT: Okay, now we've got a slightly clearer set of requirements (though still far from clearly written) the simplest approach would probably be:
var maxes = list.GroupBy(x => x.id2,
(key, xs) => xs.OrderByDescending(x => x.id1)
.First()
.value);
Unfortunately LINQ doesn't provide a simple way of getting "the element with the maximal value" (instead of the maximal value itself). I have a method in MoreLINQ which does this though, called MaxBy
:
var maxes = list.GroupBy(x => x.id2,
(key, xs) => xs.MaxBy(x => x.id2).value);
Original answer (Grouping by id2, taking the maximum value)
I'm answering assuming you actually meant to group by id2
rather than id1
, and you actually wanted the results of 12 and 87 rather than 6 and 87. In that case, you'd want:
var maxes = list.GroupBy(x => x.id2, (id, xs) => xs.Max(x => x.value));
Or (possibly simpler to understand):
var maxes = list.GroupBy(x => x.id2)
.Select(xs => xs.Max(x => x.value));
Or:
var maxes = list.GroupBy(x => x.id2, x => x.value)
.Select(values => values.Max());
Or:
var maxes = list.GroupBy(x => x.id2, // Key selector
x => x.value, // Element selector
(key, values) => values.Max()); // Result selector
Or even:
var maxes = list.GroupBy(x => x.id2)
.Select(xs => xs.Select(x => x.value).Max());
As you can see, GroupBy
has lots of overloads :)
Or you could use a query expression:
var maxes = from x in list
group x.value by x.id2 into values
select values.Max();
You shouldn't restrict yourself to either query expressions or the extension method version - it's important to understand both, so you can use whatever's most appropriate.
Solution 2
Apparently OP wants the Value
with maximum Id1
within Id2
:
Sample data:
public class Row
{
public int Id1;
public int Id2;
public int Value;
}
List<Row> rows = new List<Row>(){
new Row(){Id1=1,Id2=9,Value=12},
new Row(){Id1=2,Id2=9,Value=6},
new Row(){Id1=3,Id2=11,Value=8},
new Row(){Id1=4,Id2=11,Value=87}
};
Solution:
List<int> res = rows.GroupBy(r => r.Id2)
.Select(g => g.OrderByDescending(i=>i.Id1).First().Value)
.ToList();
Pavel
Updated on July 15, 2022Comments
-
Pavel almost 2 years
I have a collection, for example:
**id1, id2, value** 1 9 12 2 9 6 3 11 8 4 11 87
I want to use LINQ and get the following result:
**value** 6 87
P.S.
id1 - select MAX; id2 - group column;
I need an answer in the form of
var result = list.GroupBy(x=>x.id2).select(s=>s.value);
I hope for your help.