Construction d’un dictionnaire de comptes d’éléments dans une liste

J’ai une liste contenant un tas de chaînes qui peuvent se produire plus d’une fois. Je voudrais prendre cette liste et construire un dictionnaire des éléments de liste comme clé et du nombre de leurs occurrences comme valeur

Exemple:

List stuff = new List(); 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" ); 

et le résultat serait un dictionnaire contenant:

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

J’ai un moyen de faire cela, mais il ne semble pas que j’utilise les bonnes choses en C # 3.0

 public Dictionary CountStuff( IList stuffList ) { Dictionary stuffCount = new Dictionary(); foreach (ssortingng stuff in stuffList) { //initialize or increment the count for this item if (stuffCount.ContainsKey( stuff )) { stuffCount[stuff]++; } else { stuffCount.Add( stuff, 1 ); } } return stuffCount; } 

Vous pouvez utiliser la clause group en C # pour cela.

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

Vous pouvez aussi appeler directement les méthodes d’extension si vous voulez:

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

A partir de là, il suffit d’un court saut pour le placer dans un Dictionary :

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

J’aurais fait une liste spécialisée, soutenue par le dictionnaire et la méthode add, qui permettrait de tester l’adhésion et d’augmenter le nombre si trouvé.

un peu comme:

 public class CountingList { Dictionary countingList = new Dictionary(); void Add( ssortingng s ) { if( countingList.ContainsKey( s )) countingList[ s ] ++; else countingList.Add( s, 1 ); } } 

Une idée serait de donner au dictionnaire une valeur par défaut de zéro afin que vous n’ayez pas à faire la casse spéciale la première fois.

Eh bien, il n’y a pas vraiment de meilleure façon de le faire.

Vous pourriez peut-être écrire une requête LINQ qui regrouperait les chaînes, puis compter le nombre de chaînes dans chaque groupe, mais cela ne serait pas aussi efficace que ce que vous avez déjà.

 Dictionary a = stuff.GroupBy(p => p).OrderByDescending(r=>r.Count()).ToDictionary(q => q.Key, q => q.Count()); 

Vous pouvez GroupBy, puis créer un dictionnaire pour compter chaque groupe. Comme le test de performance l’ indique, il existe généralement des approches plus efficaces que Linq. Je pense que votre code est plus efficace, alors que la solution Linq est plus lisible et plus belle.