J'ai une liste d'objets Person. Je veux convertir en un dictionnaire où la clé est le prénom et le nom (concaténés) et la valeur est l'objet Person.
Le problème est que j'ai des personnes en double, donc cela explose si j'utilise ce code:
private Dictionary<string, Person> _people = new Dictionary<string, Person>();
_people = personList.ToDictionary(
e => e.FirstandLastName,
StringComparer.OrdinalIgnoreCase);
Je sais que cela semble étrange mais je ne me soucie pas vraiment des noms en double pour le moment. S'il y a plusieurs noms, je veux juste en prendre un. Est-il possible que je puisse écrire ce code ci-dessus pour qu'il ne prenne qu'un des noms et ne fasse pas exploser les doublons?
c#
linq
dictionary
Léora
la source
la source
Dictionary<string, List<Person>>
(ou équivalent).Distinct
Réponses:
Voici la solution évidente, non linq:
la source
Solution LINQ:
Si vous préférez une solution non LINQ, vous pouvez faire quelque chose comme ceci:
la source
Une solution Linq utilisant Distinct () et et aucun regroupement est:
Je ne sais pas si c'est mieux que la solution de LukeH mais ça marche aussi.
la source
Cela devrait fonctionner avec l'expression lambda:
la source
personList.Distinct().ToDictionary(i => i.FirstandLastName, i => i);
Vous pouvez également utiliser la
ToLookup
fonction LINQ, que vous pouvez ensuite utiliser presque de manière interchangeable avec un dictionnaire.Cela fera essentiellement le GroupBy dans la réponse de LukeH , mais donnera le hachage fourni par un dictionnaire. Ainsi, vous n'avez probablement pas besoin de le convertir en dictionnaire, mais utilisez simplement la
First
fonction LINQ chaque fois que vous avez besoin d'accéder à la valeur de la clé.la source
Vous pouvez créer une méthode d'extension similaire à ToDictionary (), la différence étant qu'elle autorise les doublons. Quelque chose comme:
Dans ce cas, s'il y a des doublons, la dernière valeur l'emporte.
la source
Pour gérer l'élimination des doublons, implémentez un
IEqualityComparer<Person>
qui peut être utilisé dans laDistinct()
méthode, puis obtenir votre dictionnaire sera facile. Donné:Obtenez votre dictionnaire:
la source
la source
Dans le cas où nous voulons que toute la personne (au lieu d'une seule personne) dans le dictionnaire de retour, nous pourrions:
la source
Le problème avec la plupart des autres réponses est qu'elles utilisent
Distinct
,GroupBy
ouToLookup
, ce qui crée un dictionnaire supplémentaire sous le capot. De même, ToUpper crée une chaîne supplémentaire. C'est ce que j'ai fait, qui est une copie presque exacte du code de Microsoft, à l'exception d'un changement:Étant donné qu'un ensemble sur l'indexeur lui fait ajouter la clé, il ne lancera pas et effectuera également une seule recherche de clé. Vous pouvez également lui donner un
IEqualityComparer
, par exempleStringComparer.OrdinalIgnoreCase
la source
À partir de la solution de Carra, vous pouvez également l'écrire comme:
la source