Nehmen wir an, wir haben eine Klasse wie:
class Person {
internal int PersonID;
internal string car;
}
Jetzt habe ich eine Liste dieser Klasse: List<Person> persons;
Jetzt kann diese Liste mehrere Instanzen mit denselben haben PersonID
, zum Beispiel:
persons[0] = new Person { PersonID = 1, car = "Ferrari" };
persons[1] = new Person { PersonID = 1, car = "BMW" };
persons[2] = new Person { PersonID = 2, car = "Audi" };
Gibt es eine Möglichkeit, nach der ich gruppieren PersonID
und die Liste aller Autos abrufen kann, die er hat?
Zum Beispiel wäre das erwartete Ergebnis
class Result {
int PersonID;
List<string> cars;
}
Nach der Gruppierung würde ich also bekommen:
results[0].PersonID = 1;
List<string> cars = results[0].cars;
result[1].PersonID = 2;
List<string> cars = result[1].cars;
Nach dem, was ich bisher getan habe:
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
Könnte mich bitte jemand in die richtige Richtung weisen?
Count
undSum
hier stackoverflow.com/questions/3414080/…Antworten:
Absolut - Sie wollen im Grunde:
Oder als Ausdruck ohne Abfrage:
Grundsätzlich ist der Inhalt der Gruppe (wenn als betrachtet
IEnumerable<T>
) eine Folge von Werten, die in der Projektion (p.car
in diesem Fall) für den angegebenen Schlüssel vorhanden waren.Weitere Informationen zur Funktionsweise
GroupBy
finden Sie in meinem Edulinq-Beitrag zum Thema .(Ich habe umbenannt ,
PersonID
umPersonId
in den oben genannten, zu folgen .NET - Namenskonventionen .)Alternativ können Sie Folgendes verwenden
Lookup
:Sie können dann ganz einfach die Autos für jede Person bekommen:
quelle
.GroupBy(p => new {p.Id, p.Name}, p => p, (key, g) => new { PersonId = key.Id, PersonName = key.Name, PersonCount = g.Count()})
und Sie erhalten alle Personen, die mit einer ID, einem Namen und einer Anzahl von Vorkommen für jede Person auftreten.quelle
quelle
Sie können dies auch versuchen:
quelle
Versuchen
oder
Um zu überprüfen, ob sich eine Person in Ihrer Liste wiederholt, versuchen Sie es
quelle
Ich habe ein funktionierendes Codebeispiel mit Abfragesyntax und Methodensyntax erstellt. Ich hoffe es hilft den anderen :)
Sie können den Code auch auf .Net Fiddle hier ausführen:
Hier ist das Ergebnis:
quelle
Versuche dies :
In Bezug auf die Leistung ist die folgende Vorgehensweise bei der Speichernutzung besser und optimierter (wenn unser Array viel mehr Elemente wie Millionen enthält):
quelle
g.Key.PersonId
?g.SelectMany
?? Sie haben das offensichtlich nicht versucht.SortedDictionary <PersonIdInt, SortedDictionary <CarNameString, CarInfoClass>>
. Das Beste, was ich mit LINQ erreichen konnte, warIEnumerable <IGrouping <PersonIdInt, Dictionary <CarNameString, PersonIdCarNameXrefClass>>>
. Ich habe Ihrefor
Loop-Methode beendet, die übrigens 2x schneller war. Außerdem würde ich verwenden: a)foreach
vs.for
und b)TryGetValue
vs.ContainsKey
(beide für das DRY-Prinzip - in Code & Laufzeit).Eine alternative Möglichkeit, dies zu tun, könnte darin bestehen, eine bestimmte
PersonId
Gruppe auszuwählen und sich einer Gruppe anzuschließen mitpersons
:Oder dasselbe mit fließender API-Syntax:
GroupJoin erstellt eine Liste von Einträgen in der ersten Liste (
PersonId
in unserem Fall Liste von ) mit jeweils einer Gruppe von verbundenen Einträgen in der zweiten Liste (Liste von)persons
).quelle
Im folgenden Beispiel wird die GroupBy-Methode verwendet, um Objekte zurückzugeben, nach denen gruppiert ist
PersonID
.Oder
Oder
Oder Sie können verwenden
ToLookup
. GrundsätzlichToLookup
verwendetEqualityComparer<TKey>
.Default, um Schlüssel zu vergleichen und das zu tun, was Sie manuell tun sollten, wenn Sie group by und to dictionary verwenden. Ich denke, es ist in Erinnerungquelle
Stellen Sie zunächst Ihr Schlüsselfeld ein. Fügen Sie dann Ihre anderen Felder hinzu:
quelle