2009-03-26 3 views
7

Ho una lista contenente un gruppo di stringhe che possono verificarsi più di una volta. Vorrei prendere questo elenco e creare un dizionario degli elementi della lista come chiave e il conteggio delle loro occorrenze come valore.Creazione di un dizionario di conteggi di elementi in una lista

Esempio:

List<string> stuff = new List<string>(); 
stuff.Add("Peanut Butter"); 
stuff.Add("Jam"); 
stuff.Add("Food"); 
stuff.Add("Snacks"); 
stuff.Add("Philosophy"); 
stuff.Add("Peanut Butter"); 
stuff.Add("Jam"); 
stuff.Add("Food"); 

e il risultato sarebbe un dizionario contenente:

"Peanut Butter", 2 
"Jam", 2 
"Food", 2 
"Snacks", 1 
"Philosophy", 1 

ho un modo per fare questo, ma non sembra come sto utilizzando il buon roba in C# 3,0

public Dictionary<string, int> CountStuff(IList<string> stuffList) 
{ 
    Dictionary<string, int> stuffCount = new Dictionary<string, int>(); 

    foreach (string stuff in stuffList) { 
     //initialize or increment the count for this item 
     if (stuffCount.ContainsKey(stuff)) { 
      stuffCount[stuff]++; 
     } else { 
      stuffCount.Add(stuff, 1); 
     } 
    } 

    return stuffCount; 
} 

risposta

20

È possibile utilizzare la clausola di gruppo in C# per eseguire questa operazione.

List<string> stuff = new List<string>(); 
... 

var groups = from s in stuff group s by s into g select 
    new { Stuff = g.Key, Count = g.Count() }; 

È possibile chiamare i metodi di estensione direttamente come pure se si vuole:

var groups = stuff.GroupBy(s => s).Select(
    s => new { Stuff = s.Key, Count = s.Count() }); 

Da qui si tratta di un breve salto per collocarlo in una Dictionary<string, int>:

var dictionary = groups.ToDictionary(g => g.Stuff, g => g.Count); 
+0

Come ti aggiungere un orderby al primo esempio? – zadam

+0

@zadam Puoi sempre dire 'groups = groups.OrderBy (g => g.Stuff)'; – casperOne

1

un'idea potrebbe essere quella di dare il dizionario un default value pari a zero, in modo da wou Non è necessario il caso speciale la prima occorrenza.

+0

Beh, che sarebbe solo spostare il codice che gestisce il caso particolare in una classe separata ... – Guffa

0

Beh, ci non è davvero un modo migliore per farlo.

Forse potresti scrivere una query LINQ che raggrupperebbe le stringhe e quindi conteggiare quante stringhe ci sono in ogni gruppo, ma ciò non sarebbe altrettanto efficiente di quello che hai già.

7

Avrei creato un elenco specializzato, supportato dal dizionario e il metodo add avrebbe verificato l'appartenenza e aumentato il conteggio se trovato.

piace sorta:

public class CountingList 
{ 
    Dictionary<string, int> countingList = new Dictionary<string, int>(); 

    void Add(string s) 
    { 
     if(countingList.ContainsKey(s)) 
      countingList[ s ] ++; 
     else 
      countingList.Add(s, 1); 
    } 
} 
Problemi correlati