Tengo una lista de objetos Persona. Quiero convertir a un diccionario donde la clave es el nombre y el apellido (concatenados) y el valor es el objeto Persona.
El problema es que tengo algunas personas duplicadas, por lo que esto explota si uso este código:
private Dictionary<string, Person> _people = new Dictionary<string, Person>();
_people = personList.ToDictionary(
e => e.FirstandLastName,
StringComparer.OrdinalIgnoreCase);
Sé que suena extraño, pero por ahora no me importan los nombres duplicados. Si hay varios nombres, solo quiero tomar uno. ¿Hay alguna forma de escribir este código arriba para que solo tome uno de los nombres y no explote en duplicados?
c#
linq
dictionary
leora
fuente
fuente
Dictionary<string, List<Person>>
(o equivalente).Distinct
Respuestas:
Aquí está la solución obvia, no linq:
fuente
Solución LINQ:
Si prefiere una solución que no sea LINQ, puede hacer algo como esto:
fuente
Una solución de Linq usando Distinct () y sin agrupación es:
No sé si es mejor que la solución de LukeH, pero también funciona.
fuente
Esto debería funcionar con la expresión lambda:
fuente
personList.Distinct().ToDictionary(i => i.FirstandLastName, i => i);
También puede usar la
ToLookup
función LINQ, que luego puede usar casi indistintamente con un Diccionario.Esto esencialmente hará el GroupBy en la respuesta de LukeH , pero dará el hash que proporciona un Diccionario. Por lo tanto, es probable que no necesite convertirlo a un diccionario, sino que simplemente use la
First
función LINQ cuando necesite acceder al valor de la clave.fuente
Puede crear un método de extensión similar a ToDictionary () con la diferencia de que permite duplicados. Algo como:
En este caso, si hay duplicados, gana el último valor.
fuente
Para manejar la eliminación de duplicados, implemente uno
IEqualityComparer<Person>
que pueda usarse en elDistinct()
método, y luego obtener su diccionario será fácil. Dado:Consigue tu diccionario:
fuente
fuente
En caso de que queramos toda la Persona (en lugar de una sola Persona) en el diccionario que regresa, podríamos:
fuente
El problema con la mayoría de las otras respuestas es que usan
Distinct
,GroupBy
oToLookup
, lo que crea un diccionario adicional debajo del capó. Igualmente ToUpper crea una cadena extra. Esto es lo que hice, que es casi una copia exacta del código de Microsoft, excepto por un cambio:Debido a que un conjunto en el indexador hace que agregue la clave, no arrojará, y también realizará solo una búsqueda de clave. También puedes darle un
IEqualityComparer
, por ejemploStringComparer.OrdinalIgnoreCase
fuente
A partir de la solución de Carra, también puede escribirlo como:
fuente