2012-03-29 16 views
7

Ho una lista che voglio mettere in un dizionario, per semplicità i valori inseriti saranno tutti uguali.C# ToDictionary con ContainsKey check

Posso usare un ciclo foreach.

List<string> list = new List<string>(); 
    list.Add("Earth"); 
    list.Add("Wind"); 
    list.Add("Fire"); 
    list.Add("Water"); 
    list.Add("Water"); // Will NOT BE INSERTED using the foreach loop 

    var myDictionary= new Dictionary<string, int>(); 
    foreach (string value in list) 
    { 
     if (!myDictionary.ContainsKey(value)) 
     { 
     myDictionary.Add(value, 1); 
     } 
    } 

Quanto sopra funziona.

ma voglio utilizzare ToDictionary fare lo stesso nel modo seguente -

Dictionary<string, int> myDictionary2 = list.ToDictionary(i => i, i => 1); 

Naturalmente questo non riesce perché sto aggiungendo "Acqua" due volte.

Qual è il modo corretto di verificare la presenza di voci duplicate quando si utilizza ToDictionary?

risposta

14

Si potrebbe utilizzare Distinct() per filtrare i duplicati:

Dictionary<string, int> myDictionary2 = list.Distinct().ToDictionary(i => i, i => 1); 

Lo stesso approccio potrebbe rendere il vostro ciclo tradizionale molto più chiara troppo, dal momento che non controlla "manualmente" i duplicati:

foreach (string value in list.Distinct()) 
{ 
    myDictionary.Add(value, 1); 
} 
+6

Questo funzionerà, ma mi chiedo se OP vuole davvero un set. – Gabe

+0

@Gabe: Non sono sicuro di non capire il tuo commento nel contesto della domanda - puoi chiarire? – BrokenGlass

+1

Un dizionario in cui tutti i valori sono 1 è essenzialmente un set. Se l'utente non accede mai ai valori, non è necessario un dizionario reale. – Gabe

7

Distinct è un'opzione che evita il problema della chiave duplicata. Se avete bisogno di un conteggio di duplicati, si potrebbe provare qualcosa di più simile a questo GroupBy come segue:

var dict = list.GroupBy(i => i).ToDictionary(g => g.Key, g => g.Count()); 

Se l'applicazione non è solo una struttura semplice stringa-list/duplicate-count, si potrebbe ottenere un po 'di distanza in miglia dalla scelta una struttura diversa come un Lookup che è possibile ottenere chiamando l'estensione ToLookup -o possibilmente andando con un Raggruppamento come lo GroupBy che ho usato sopra.