Eu tenho uma lista de objetos Pessoa. Quero converter para um dicionário em que a chave seja o nome e o sobrenome (concatenados) e o valor seja o objeto Pessoa.
O problema é que eu tenho algumas pessoas duplicadas, então isso explode se eu usar este código:
private Dictionary<string, Person> _people = new Dictionary<string, Person>();
_people = personList.ToDictionary(
e => e.FirstandLastName,
StringComparer.OrdinalIgnoreCase);
Sei que parece estranho, mas não me preocupo com nomes duplicados por enquanto. Se houver vários nomes, eu só quero pegar um. Existe alguma maneira que eu possa escrever esse código acima, então ele pega um dos nomes e não explode em duplicatas?
c#
linq
dictionary
leora
fonte
fonte
Dictionary<string, List<Person>>
(ou equivalente).Distinct
Respostas:
Aqui está a solução óbvia e não linq:
fonte
Solução LINQ:
Se você preferir uma solução não-LINQ, poderá fazer algo assim:
fonte
Uma solução Linq usando Distinct () e sem agrupamento é:
Não sei se é melhor que a solução de LukeH, mas também funciona.
fonte
Isso deve funcionar com a expressão lambda:
fonte
personList.Distinct().ToDictionary(i => i.FirstandLastName, i => i);
Você também pode usar a
ToLookup
função LINQ, que você pode usar quase de forma intercambiável com um dicionário.Isso fará essencialmente o GroupBy na resposta de LukeH , mas fornecerá o hash que um Dicionário fornece. Portanto, você provavelmente não precisará convertê-lo em um dicionário, mas use a
First
função LINQ sempre que precisar acessar o valor da chave.fonte
Você pode criar um método de extensão semelhante ao ToDictionary (), com a diferença de que ele permite duplicatas. Algo como:
Nesse caso, se houver duplicatas, o último valor vence.
fonte
Para lidar com a eliminação de duplicatas, implemente uma
IEqualityComparer<Person>
que possa ser usada noDistinct()
método e obter o seu dicionário será fácil. Dado:Obtenha seu dicionário:
fonte
fonte
Caso desejemos toda a Pessoa (em vez de apenas uma Pessoa) no dicionário retornado, poderíamos:
fonte
O problema com a maioria das outras respostas é que elas usam
Distinct
,GroupBy
ouToLookup
, o que cria um dicionário extra sob o capô. Igualmente, o ToUpper cria uma sequência extra. Foi o que fiz, que é uma cópia quase exata do código da Microsoft, exceto por uma alteração:Como um conjunto no indexador faz com que ele adicione a chave, ele não será acionado e também fará apenas uma pesquisa de chave. Você também pode fornecer
IEqualityComparer
, por exemploStringComparer.OrdinalIgnoreCase
fonte
A partir da solução de Carra, você também pode escrevê-lo como:
fonte