Stel dat we een klasse hebben als
class Person {
internal int PersonID;
internal string car ;
}
Nu heb ik een lijst van deze klasse: List<Person> persons;
Nu kan deze lijst meerdere instanties hebben met dezelfde PersonIDs, bijvoorbeeld:
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 er een manier waarop ik kan groeperen op personID
en de lijst kan krijgen van alle auto's die hij heeft?
Bijvoorbeeld, het verwachte resultaat zou zijn
class Result {
int PersonID;
List<string> cars;
}
Dus na groepering, zou ik krijgen:
results[0].PersonID = 1;
List<string> cars = results[0].cars;
result[1].PersonID = 2;
List<string> cars = result[1].cars;
Van wat ik tot nu toe gedaan heb:
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
Kan iemand me alsjeblieft in de juiste richting wijzen?
Absoluut. Je wilt eigenlijk:
var results = from p in persons
group p.car by p.PersonId into g
select new { PersonId = g.Key, Cars = g.ToList() };
Of als een niet-query expressie:
var results = persons.GroupBy(
p => p.PersonId,
p => p.car,
(key, g) => new { PersonId = key, Cars = g.ToList() });
In principe is de inhoud van de groep (als IEnumerable<T>
) een opeenvolging van alle waarden die in de projectie (p.car
in dit geval) aanwezig waren voor de gegeven sleutel.
Voor meer over hoe GroupBy
werkt, zie mijn Edulinq post over het onderwerp.
(Ik heb PersonID
hernoemd naar PersonId
in het bovenstaande, om de .NET naamgevingsconventies te volgen).
Als alternatief zou je een Lookup
kunnen gebruiken:
var carsByPersonId = persons.ToLookup(p => p.PersonId, p => p.car);
U kunt dan heel gemakkelijk de auto's van elke persoon krijgen:
// This will be an empty sequence for any personId not in the lookup
var carsForPerson = carsByPersonId[personId];
var results = from p in persons
group p by p.PersonID into g
select new { PersonID = g.Key, Cars = g.Select(m => m.car) };