C # Converter lista <string> em Dicionário <string, string>

117

Pode parecer uma coisa estranha de se querer, mas, ignorando isso, existe uma maneira concisa e agradável de converter uma Lista em Dicionário, onde cada Par de Valores-Chave no Dicionário é apenas cada string na Lista. ie

List = string1, string2, string3
Dictionary = string1/string1, string2/string2, string3/string3

Eu fiz muitas pesquisas e existem literalmente dezenas de exemplos no Stackoverflow sozinho de fazer isso na direção oposta, mas não desta forma.

A razão para fazer isso é que eu tenho dois componentes de terceiros e alterá-los está fora de minhas mãos. Um retorna uma lista de endereços de e-mail como uma Lista e o outro envia e-mails onde o parâmetro Para é um Dicionário. A chave do dicionário é o endereço de e-mail e o valor é o nome real. No entanto, não sei o nome real, mas ainda funciona se você definir o nome real como o endereço de e-mail também. Portanto, por que quero converter uma lista em um dicionário. Existem muitas maneiras de fazer isso. Um loop foreach na lista que adiciona um kvp a um dicionário. Mas eu gosto de código conciso e me pergunto se existe uma solução de uma única linha.

Jonnster
fonte
1
Eu tenho uma solução melhor para seu motivo válido, honesto.
2
Você pode querer ver se o HashSet <> atende aos seus requisitos, em vez de usar o Dicionário <,>.
Greg
Mais diretamente do que os comentadores acima: Se você explicar sua razão para querer isso, alguém provavelmente pode sugerir uma solução melhor.
Tim S.
1
Não existe solução melhor. Eu tenho um componente de terceiros que retorna uma lista de strings, estes são endereços de e-mail. Eu tenho outro componente de terceiros que envia e-mails onde passa um Dicionário <string, string> onde a chave é o endereço de e-mail e o valor é o nome real do destinatário. No entanto, o nome real também pode ser apenas o endereço de e-mail novamente, e é por isso que desejo converter uma List <string> em um Dicionário <string, string>
Jonnster

Respostas:

243

Experimente isto:

var res = list.ToDictionary(x => x, x => x);

O primeiro lambda permite que você escolha a chave, o segundo escolhe o valor.

Você pode brincar com ele e fazer com que os valores sejam diferentes das chaves, assim:

var res = list.ToDictionary(x => x, x => string.Format("Val: {0}", x));

Se a sua lista contém duplicatas, adicione Distinct()assim:

var res = list.Distinct().ToDictionary(x => x, x => x);

EDITAR Para comentar sobre o motivo válido, acho que o único motivo que poderia ser válido para conversões como essa é que em algum ponto as chaves e os valores no dicionário resultante irão divergir. Por exemplo, você faria uma conversão inicial e, em seguida, substituiria alguns dos valores por outra coisa. Se as chaves e os valores forem sempre os mesmos, HashSet<String>seria um ajuste muito melhor para sua situação:

var res = new HashSet<string>(list);
if (res.Contains("string1")) ...
dasblinkenlight
fonte
isso falhará se a lista for como string1, string2, string3, string1
Pranay Rana
3
@PranayRana Sim, seria. Você pode adicionar .Distinct()depois listpara evitar isso.
dasblinkenlight de
Obrigado. Perdi a função ToDictionary. Obrigado a todos que basicamente deram a mesma resposta. Eu votei a favor de todos, mas só posso aceitar uma resposta. Este era apenas um com o código Distinct adicionado, então era o mais completo na minha opinião.
Jonnster de
11

Usa isto:

var dict = list.ToDictionary(x => x);

Consulte MSDN para obter mais informações.

Como Pranay aponta nos comentários, isso falhará se um item existir na lista várias vezes.
Dependendo de seus requisitos específicos, você pode usar var dict = list.Distinct().ToDictionary(x => x);para obter um dicionário de itens distintos ou pode usar ToLookup:

var dict = list.ToLookup(x => x);

Isso retornará um ILookup<string, string>que é essencialmente o mesmo que IDictionary<string, IEnumerable<string>>, portanto, você terá uma lista de chaves distintas com cada instância de string abaixo dela.

Daniel Hilgarth
fonte
isso falhará se a lista for como string1, string2, string3, string1
Pranay Rana
1

Usando ToDictionary:

var dictionary = list.ToDictionary(s => s);

Se for possível que qualquer string possa ser repetida, faça uma Distinctchamada primeiro na lista (para remover duplicatas) ou use o ToLookupque permite vários valores por chave.

Lukazoid
fonte
0

Você pode usar:

var dictionary = myList.ToDictionary(x => x);
dtsg
fonte
0

EDITAR

outra maneira de lidar com duplicatas é fazer assim

var dic = slist.Select((element, index)=> new{element,index} )
            .ToDictionary(ele=>ele.index.ToString(), ele=>ele.element);

ou


maneira fácil de fazer é

var res = list.ToDictionary(str => str, str=> str); 

mas certifique-se de que nenhuma string está se repetindo ... novamente, caso contrário, o código acima não funcionará para você

se houver string repetindo, então é melhor fazer assim

Dictionary<string,string> dic= new Dictionary<string,string> ();

    foreach(string s in Stringlist)
    {
       if(!dic.ContainsKey(s))
       {
        //  dic.Add( value to dictionary
      }
    }
Pranay Rana
fonte