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[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 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[0].PersonID = 1;
List<string> cars = results[0].cars;
result[1].PersonID = 2;
List<string> cars = result[1].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.
Asked by test123
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];
Answered by Jon Skeet
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()/**/}
Answered by Tallat
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();
Answered by shuvo sarker
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) };
Answered by Yogendra Paudyal
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)
Answered by Code First
Post is based on https://stackoverflow.com/questions/7325278/group-by-in-linq