2009-07-16 9 views
37

C'è un modo semplice per contare il numero di occorrenze di tutti gli elementi di un elenco in quello stesso elenco in C#?Un metodo per contare le occorrenze in un elenco

Qualcosa di simile a questo:

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]); 
    } 
} 

risposta

67

Che ne dite di qualcosa di simile ...

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()); 
} 

Edit per commentare: cercherò di fare questa giustizia. :)

Nel mio esempio, è un Func<int, TKey> perché la mia lista è ints. Quindi, sto dicendo a GroupBy come raggruppare i miei articoli. Il Func prende un int e restituisce la chiave per il mio raggruppamento. In questo caso, otterrò un IGrouping<int,int> (un raggruppamento di interi immesso da un int). Ad esempio, se l'ho modificato in (i => i.ToString()), inserirò il mio raggruppamento in base a una stringa. Puoi immaginare un esempio meno banale del keying di "1", "2", "3" ... forse faccio una funzione che restituisce "uno", "due", "tre" per essere le mie chiavi ...

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

Quindi, questo è un Funz che avrebbe preso un int e restituire una stringa, proprio come ...

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

Ma, dal momento che la domanda iniziale chiamato per conoscere il valore della lista originale e del conte, Ho appena usato un numero intero per digitare il mio gruppo intero per semplificare il mio esempio.

+1

+1. questo è molto elegante per contare l'occorrenza di ogni singolo elemento. –

+0

E riguardo list.FindAll? – CodeFusionMobile

+0

FindAll restituisce un elenco di elementi dall'elenco originale che corrispondono a un predicato, quindi sarà necessario farlo una volta per ciascun elemento univoco per trovare il conteggio per quell'elemento. –

-1

vostro ciclo esterno è un loop su tutte le parole della lista. Non è necessario e ti causerà problemi. Rimuovilo e dovrebbe funzionare correttamente.

7

Si può fare qualcosa del genere per contare da una lista di cose.

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(); 

di contare un singolo elemento

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

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

+1: Mi c'è voluto un po 'per capire che GetMethods() era solo vostra lista di cose. :) –

+0

sì, ci ho pensato e ho deciso di renderlo più leggibile. grazie, anche se ho letto male la domanda. Dice di contare "tutto l'elemento" .. ooops. Questo dovrebbe essere ancora abbastanza utile. –

+0

@StanR. - questa soluzione funziona per il mio problema. Tuttavia, c'è un metodo sulla lista in cui posso contare l'occorrenza maggiore o uguale a nelle parole? Sto usando il tipo "int" invece di "string". –

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

Questo è tratto da uno degli esempi nella LINQPad