Supposons que si nous avons une classe comme:
class Person {
internal int PersonID;
internal string car;
}
Maintenant, j'ai une liste de cette classe: List<Person> persons;
Maintenant, cette liste peut avoir plusieurs instances avec les mêmes PersonID
, par exemple:
persons[0] = new Person { PersonID = 1, car = "Ferrari" };
persons[1] = new Person { PersonID = 1, car = "BMW" };
persons[2] = new Person { PersonID = 2, car = "Audi" };
Existe-t-il un moyen de me regrouper PersonID
et d'obtenir la liste de toutes les voitures qu'il a?
Par exemple, le résultat attendu serait
class Result {
int PersonID;
List<string> cars;
}
Donc après le regroupement, j'obtiendrais:
results[0].PersonID = 1;
List<string> cars = results[0].cars;
result[1].PersonID = 2;
List<string> cars = result[1].cars;
D'après ce que j'ai fait jusqu'à présent:
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
Quelqu'un pourrait-il m'orienter dans la bonne direction?
Count
etSum
ici stackoverflow.com/questions/3414080/…Réponses:
Absolument - vous voulez essentiellement:
Ou en tant qu'expression sans requête:
Fondamentalement, le contenu du groupe (lorsqu'il est considéré comme un
IEnumerable<T>
) est une séquence de toutes les valeurs présentes dans la projection (p.car
dans ce cas) présente pour la clé donnée.Pour en savoir plus sur le
GroupBy
fonctionnement, consultez mon article Edulinq sur le sujet .(Je l' ai retitré
PersonID
àPersonId
dans ce qui précède, de suivre les conventions de nommage .NET .)Alternativement, vous pouvez utiliser
Lookup
:Vous pouvez alors obtenir les voitures pour chaque personne très facilement:
la source
.GroupBy(p => new {p.Id, p.Name}, p => p, (key, g) => new { PersonId = key.Id, PersonName = key.Name, PersonCount = g.Count()})
et vous obtiendrez toutes les personnes qui se produisent avec un identifiant, un nom et un certain nombre d'occurrences pour chaque personne.la source
la source
Vous pouvez également essayer ceci:
la source
essayer
ou
pour vérifier si une personne se répète dans votre liste, essayez
la source
J'ai créé un exemple de code de travail avec la syntaxe de requête et la syntaxe de méthode. J'espère que ça aide les autres :)
Vous pouvez également exécuter le code sur .Net Fiddle ici:
Voici le résultat:
la source
Essaye ça :
Mais en termes de performances, la pratique suivante est meilleure et plus optimisée dans l'utilisation de la mémoire (lorsque notre tableau contient beaucoup plus d'éléments comme des millions):
la source
g.Key.PersonId
?g.SelectMany
?? Vous n'avez clairement pas essayé cela.SortedDictionary <PersonIdInt, SortedDictionary <CarNameString, CarInfoClass>>
. Le plus proche que j'ai pu obtenir en utilisant LINQ étaitIEnumerable <IGrouping <PersonIdInt, Dictionary <CarNameString, PersonIdCarNameXrefClass>>>
. J'ai fini par utiliser votrefor
méthode de boucle qui, au fait, était 2x plus rapide. Aussi, j'utiliserais: a)foreach
vsfor
et b)TryGetValue
vsContainsKey
(les deux pour le principe DRY - en code et en runtime).Une autre façon de procéder pourrait être de sélectionner un
PersonId
groupe distinct et de se joindre àpersons
:Ou la même chose avec une syntaxe API fluide:
GroupJoin produit une liste d'entrées dans la première liste (liste de
PersonId
dans notre cas), chacune avec un groupe d'entrées jointes dans la deuxième liste (liste depersons
).la source
L'exemple suivant utilise la méthode GroupBy pour renvoyer des objets regroupés par
PersonID
.Ou
Ou
Ou vous pouvez utiliser
ToLookup
,ToLookup
utilise essentiellementEqualityComparer<TKey>
.Default pour comparer les clés et faire ce que vous devez faire manuellement lorsque vous utilisez le regroupement par et dans le dictionnaire. je pense que c'est inmemory excutedla source
Tout d'abord, définissez votre champ clé. Incluez ensuite vos autres champs:
la source