# In LINQ, group by

## Problem

Let’s say we have a class called:

``````class Person {
internal int PersonID;
internal string car;
}
``````

I’ve made a list of the students in this class: Persons in a list;

And, for example, this list can have many instances with the same PersonIDs:

``````persons = new Person { PersonID = 1, car = "Ferrari" };
persons = new Person { PersonID = 1, car = "BMW"     };
persons = new Person { PersonID = 2, car = "Audi"    };
``````

Is there a way to get a list of all the cars he owns by grouping by PersonID?

The expected outcome, for example, would be

``````class Result {
int PersonID;
List<string> cars;
}
``````

So, after grouping, I’d have:

``````results.PersonID = 1;
List<string> cars = results.cars;

result.PersonID = 2;
List<string> cars = result.cars;
``````

So far, I’ve done the following:

``````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 do
``````

I’d appreciate it if someone could lead me in the correct place.

## Solution #1

Without a doubt, you’re looking for:

``````var results = from p in persons
group p.car by p.PersonId into g
select new { PersonId = g.Key, Cars = g.ToList() };
``````

Alternatively, as a non-query expression:

``````var results = persons.GroupBy(
p => p.PersonId,
p => p.car,
(key, g) => new { PersonId = key, Cars = g.ToList() });
``````

When regarded as an IEnumerableT>, the contents of the group are just a sequence of whatever values were present in the projection (p.car in this case) for the given key.

See my Edulinq post on the subject for more information on how GroupBy works.

(To comply with.NET naming rules, I’ve renamed PersonID to PersonId in the above.)

Another option is to utilize a Lookup:

``````var carsByPersonId = persons.ToLookup(p => p.PersonId, p => p.car);
``````

The automobiles for each person can then be simply obtained:

``````// This will be an empty sequence for any personId not in the lookup
var carsForPerson = carsByPersonId[personId];
``````

## Solution #2

``````var results = from p in persons
group p by p.PersonID into g
select new { PersonID = g.Key,
/**/car = g.Select(g=>g.car).FirstOrDefault()/**/}
``````

## Solution #3

You could also try:

``````var results= persons.GroupBy(n => new { n.PersonId, n.car})
.Select(g => new {
g.Key.PersonId,
g.Key.car)}).ToList();
``````

## Solution #4

``````var results = from p in persons
group p by p.PersonID into g
select new { PersonID = g.Key, Cars = g.Select(m => m.car) };
``````

## Solution #5

try

``````persons.GroupBy(x => x.PersonId).Select(x => x)
``````

or

Try to see if any of the people on your list are repeating themselves.

``````persons.GroupBy(x => x.PersonId).Where(x => x.Count() > 1).Any(x => x)
``````