2009-07-16 5 views
37

Existe-t-il un moyen simple de compter le nombre d'occurrences de tous les éléments d'une liste dans cette même liste en C#?Une méthode pour compter les occurrences dans une liste

Quelque chose comme ceci:

using System; 
using System.IO; 
using System.Text.RegularExpressions; 
using System.Collections.Generic; 
using System.Linq; 

string Occur; 
List<string> Words = new List<string>(); 
List<string> Occurrences = new List<string>(); 

// ~170 elements added. . . 

for (int i = 0;i<Words.Count;i++){ 
    Words = Words.Distinct().ToList(); 
    for (int ii = 0;ii<Words.Count;ii++){Occur = new Regex(Words[ii]).Matches(Words[]).Count;} 
     Occurrences.Add (Occur); 
     Console.Write("{0} ({1}), ", Words[i], Occurrences[i]); 
    } 
} 

Répondre

67

Que diriez-vous quelque chose comme ça ...

var l1 = new List<int>() { 1,2,3,4,5,2,2,2,4,4,4,1 }; 

var g = l1.GroupBy(i => i); 

foreach(var grp in g) 
{ 
    Console.WriteLine("{0} {1}", grp.Key, grp.Count()); 
} 

Modifier par commentaire: Je vais essayer de faire justice. :)

Dans mon exemple, c'est un Func<int, TKey> car ma liste est ints. Donc, je dis à GroupBy comment regrouper mes articles. Le Func prend un int et retourne la clé pour mon groupement. Dans ce cas, j'obtiendrai un IGrouping<int,int> (un regroupement d'ints codés par un int). Si je l'ai changé à (i => i.ToString()) par exemple, je serais en train de saisir mon groupe par une chaîne. Vous pouvez imaginer un exemple moins trivial que de saisir "1", "2", "3" ... peut-être que je crée une fonction qui retourne "un", "deux", "trois" pour être mes clés ...

private string SampleMethod(int i) 
{ 
    // magically return "One" if i == 1, "Two" if i == 2, etc. 
} 

donc, c'est un Func qui prendrait un entier et retourner une chaîne, tout comme ...

i => // magically return "One" if i == 1, "Two" if i == 2, etc. 

Mais, puisque la question dite originale de connaître la valeur de la liste initiale et il est comte, Je viens d'utiliser un entier pour mettre en clé mon regroupement d'entiers pour rendre mon exemple plus simple.

+1

+1. c'est très élégant de compter l'occurrence de chaque élément distinct. –

+0

Qu'en est-il de list.FindAll? – CodeFusionMobile

+0

FindAll renvoie une liste d'éléments de la liste d'origine correspondant à un prédicat. Vous devez donc le faire une fois pour chaque élément unique afin de trouver le nombre d'éléments correspondant à cet élément. –

-1

Votre boucle extérieure est en boucle sur tous les mots de la liste. C'est inutile et vous causera des problèmes. Retirez-le et cela devrait fonctionner correctement.

7

Vous pouvez faire quelque chose comme ça pour compter à partir d'une liste de choses.

IList<String> names = new List<string>() { "ToString", "Format" }; 
IEnumerable<String> methodNames = typeof(String).GetMethods().Select(x => x.Name); 

int count = methodNames.Where(x => names.Contains(x)).Count(); 

Pour compter un seul élément

string occur = "Test1"; 
IList<String> words = new List<string>() {"Test1","Test2","Test3","Test1"}; 

int count = words.Where(x => x.Equals(occur)).Count(); 
+1

+1: Il m'a fallu un certain temps pour comprendre que GetMethods() était juste votre liste de choses. :) –

+0

ouais, j'ai pensé à cela et j'ai décidé de le rendre plus lisible. merci, même si j'ai mal lu la question. Il dit de compter "tout l'élément" .. ooops. Cela devrait toujours être utile. –

+0

@StanR. - Cette solution fonctionne pour mon problème. Cependant, y a-t-il une méthode sur la liste où je peux compter l'occurrence supérieure ou égale à des mots? J'utilise le type "int" au lieu de "string". –

11
var wordCount = 
    from word in words 
    group word by word into g 
    select new { g.Key, Count = g.Count() };  

Ceci est tiré de l'un des exemples dans le LINQPad

Questions connexes