patterncsharpCritical
Group by in LINQ
Viewed 0 times
grouplinqstackoverflow
Problem
Let's suppose that we have a class like:
I have a list of this class:
And this list can have multiple instances with the same
Is there a way I can group by
For example, the expected result would be
So after grouping, I would get:
From what I have done so far:
Could someone please point me in the right direction?
class Person {
internal int PersonID;
internal string car;
}I have a list of this class:
List persons;And this list can have multiple instances with the same
PersonIDs, for example:persons[0] = new Person { PersonID = 1, car = "Ferrari" };
persons[1] = new Person { PersonID = 1, car = "BMW" };
persons[2] = new Person { PersonID = 2, car = "Audi" };Is there a way I can group by
PersonID and get the list of all the cars he has?For example, the expected result would be
class Result {
int PersonID;
List cars;
}So after grouping, I would get:
results[0].PersonID = 1;
List cars = results[0].cars;
result[1].PersonID = 2;
List cars = result[1].cars;From what I have done so far:
var results = from p in persons
group p by p.PersonID into g
select new { PersonID = g.Key, // this is where I am not sure what to doCould someone please point me in the right direction?
Solution
Absolutely - you basically want:
Or as a non-query expression:
Basically the contents of the group (when viewed as an
For more on how
(I've renamed
Alternatively, you could use a
You can then get the cars for each person very easily:
var results = from p in persons
group p.car by p.PersonId into g
select new { PersonId = g.Key, Cars = g.ToList() };Or as a non-query expression:
var results = persons.GroupBy(
p => p.PersonId,
p => p.car,
(key, g) => new { PersonId = key, Cars = g.ToList() });Basically the contents of the group (when viewed as an
IEnumerable) is a sequence of whatever values were in the projection (p.car in this case) present for the given key.For more on how
GroupBy works, see my Edulinq post on the topic.(I've renamed
PersonID to PersonId in the above, to follow .NET naming conventions, which specifically call this out in the "Capitalizing Compound Words and Common Terms" section.)Alternatively, you could use a
Lookup:var carsByPersonId = persons.ToLookup(p => p.PersonId, p => p.car);You can then get the cars for each person very easily:
// This will be an empty sequence for any personId not in the lookup
var carsForPerson = carsByPersonId[personId];Code Snippets
var results = from p in persons
group p.car by p.PersonId into g
select new { PersonId = g.Key, Cars = g.ToList() };var results = persons.GroupBy(
p => p.PersonId,
p => p.car,
(key, g) => new { PersonId = key, Cars = g.ToList() });var carsByPersonId = persons.ToLookup(p => p.PersonId, p => p.car);// This will be an empty sequence for any personId not in the lookup
var carsForPerson = carsByPersonId[personId];Context
Stack Overflow Q#7325278, score: 2115
Revisions (0)
No revisions yet.