Let\'s suppose if we have a class like:
class Person {
internal int PersonID;
internal string car;
}
I have a list of this class
First, set your key field. Then include your other fields:
var results =
persons
.GroupBy(n => n.PersonId)
.Select(r => new Result {PersonID = r.Key, Cars = r.ToList() })
.ToList()
You can also Try this:
var results= persons.GroupBy(n => new { n.PersonId, n.car})
.Select(g => new {
g.Key.PersonId,
g.Key.car)}).ToList();
An alternative way to do this could be select distinct PersonId
and group join with persons
:
var result =
from id in persons.Select(x => x.PersonId).Distinct()
join p2 in persons on id equals p2.PersonId into gr // apply group join here
select new
{
PersonId = id,
Cars = gr.Select(x => x.Car).ToList(),
};
Or the same with fluent API syntax:
var result = persons.Select(x => x.PersonId).Distinct()
.GroupJoin(persons, id => id, p => p.PersonId, (id, gr) => new
{
PersonId = id,
Cars = gr.Select(x => x.Car).ToList(),
});
GroupJoin produces a list of entries in the first list ( list of PersonId
in our case), each with a group of joined entries in the second list (list of persons
).
Try this :
var results= persons.GroupBy(n => n.PersonId)
.Select(g => new {
PersonId=g.Key,
Cars=g.Select(p=>p.car).ToList())}).ToList();
But performance-wise the following practice is better and more optimized in memory usage (when our array contains much more items like millions):
var carDic=new Dictionary<int,List<string>>();
for(int i=0;i<persons.length;i++)
{
var person=persons[i];
if(carDic.ContainsKey(person.PersonId))
{
carDic[person.PersonId].Add(person.car);
}
else
{
carDic[person.PersonId]=new List<string>(){person.car};
}
}
//returns the list of cars for PersonId 1
var carList=carDic[1];