C # Converti List <string> in Dictionary <string, string>


117

Questa può sembrare una cosa strana da fare, ma ignorandola, c'è un modo simpatico e conciso di convertire una lista in dizionario in cui ogni coppia di valori chiave nel dizionario è solo ogni stringa nella lista. vale a dire

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

Ho fatto molte ricerche e ci sono letteralmente dozzine di esempi solo su Stackoverflow di farlo nella direzione opposta ma non in questo modo.

Il motivo per farlo è che ho due componenti di terze parti e cambiarli non è nelle mie mani. Uno restituisce un elenco di indirizzi di posta elettronica come elenco e l'altro invia messaggi di posta elettronica in cui il parametro A è un dizionario. La chiave del dizionario è l'indirizzo email e il valore è il loro vero nome. Tuttavia, non conosco il vero nome ma funziona ancora se imposti anche il vero nome all'indirizzo e-mail. Quindi perché voglio convertire un elenco in un dizionario. Ci sono molti modi per farlo. Un ciclo foreach nell'elenco che aggiunge un kvp a un dizionario. Ma mi piace il codice conciso e mi chiedevo se ci fosse una soluzione a riga singola.


1
Ho una soluzione migliore per la tua valida ragione, onesto.

2
Potresti voler vedere se HashSet <> soddisfa i tuoi requisiti, invece di usare Dictionary <,>.
Greg

Più direttamente dei commentatori di cui sopra: se spieghi il motivo per cui lo desideri, qualcuno può probabilmente suggerire una soluzione migliore.
Tim S.

1
Non c'è soluzione migliore. Ho un componente di terze parti che restituisce un elenco di stringhe, questi sono indirizzi email. Ho un altro componente di terze parti che invia e-mail in cui passa un Dictionary <string, string> dove la chiave è l'indirizzo e-mail e il valore è il vero nome del destinatario. Tuttavia, il vero nome può anche essere solo di nuovo l'indirizzo e-mail, motivo per cui voglio convertire un List <string> in un Dictionary <string, string>
Jonnster

Risposte:


244

Prova questo:

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

Il primo lambda ti consente di scegliere la chiave, il secondo seleziona il valore.

Puoi giocare con esso e rendere i valori diversi dalle chiavi, in questo modo:

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

Se il tuo elenco contiene duplicati, aggiungi in Distinct()questo modo:

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

EDIT Per commentare il motivo valido, penso che l'unico motivo che potrebbe essere valido per conversioni come questa è che a un certo punto le chiavi ei valori nel dizionario risultante divergeranno. Ad esempio, dovresti eseguire una conversione iniziale e quindi sostituire alcuni valori con qualcos'altro. Se le chiavi e i valori saranno sempre gli stessi, HashSet<String>si adatterebbe molto meglio alla tua situazione:

var res = new HashSet<string>(list);
if (res.Contains("string1")) ...

questo fallirà se la lista è come stringa1, stringa2, stringa3, stringa1
Pranay Rana

3
@PranayRana Sì, lo sarebbe. Puoi aggiungere .Distinct()dopo listper evitarlo.
dasblinkenlight

Grazie. Ho perso la funzione ToDictionary. Grazie a tutti coloro che in pratica hanno dato la stessa risposta. Ho votato tutti ma posso accettare solo una risposta. Questo era solo uno con il codice Distinct aggiunto, quindi era il più completo secondo me.
Jonnster

11

Usa questo:

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

Vedi MSDN per maggiori informazioni.

Come sottolinea Pranay nei commenti, questo fallirà se un elemento è presente nell'elenco più volte.
A seconda delle tue esigenze specifiche, puoi utilizzare var dict = list.Distinct().ToDictionary(x => x);per ottenere un dizionario di elementi distinti oppure puoi utilizzare ToLookupinvece:

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

Questo restituirà un ILookup<string, string>che è essenzialmente lo stesso di IDictionary<string, IEnumerable<string>>, quindi avrai un elenco di chiavi distinte con ogni istanza di stringa sotto di esso.


questo fallirà se la lista è come stringa1, stringa2, stringa3, stringa1
Pranay Rana

1

Utilizzando ToDictionary:

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

Se è possibile che qualsiasi stringa possa essere ripetuta, eseguire Distinctprima una chiamata nell'elenco (per rimuovere i duplicati) o utilizzare ToLookupche consente più valori per chiave.


0

Puoi usare:

var dictionary = myList.ToDictionary(x => x);

0

MODIFICARE

un altro modo per gestire i duplicati è che puoi fare in questo modo

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

o


il modo più semplice per farlo è

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

ma assicurati che non ci sia alcuna stringa che si ripeta ... di nuovo altrimenti il ​​codice sopra non funzionerà per te

se c'è una stringa che si ripete, è meglio fare così

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

    foreach(string s in Stringlist)
    {
       if(!dic.ContainsKey(s))
       {
        //  dic.Add( value to dictionary
      }
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.