2009-07-16 12 views
37

¿Hay una manera simple de contar el número de ocurrencias de todos los elementos de una lista en esa misma lista en C#?Un método para contar las ocurrencias en una lista

Algo como esto:

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

Respuesta

67

¿Qué tal algo como esto ...

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

Editar por comentario: Voy a tratar de hacer justicia. :)

En mi ejemplo, es un Func<int, TKey> porque mi lista es ints. Entonces, le digo a GroupBy cómo agrupar mis artículos. El Func toma un int y devuelve la clave para mi agrupación. En este caso, obtendré un IGrouping<int,int> (una agrupación de entradas codificada por un int). Si lo cambiara a (i => i.ToString()) por ejemplo, estaría marcando mi agrupación por una cadena. Puedes imaginar un ejemplo menos trivial que tecleando "1", "2", "3" ... tal vez haga una función que devuelva "uno", "dos", "tres" para que sean mis llaves ...

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

por lo tanto, eso es un Func que tomaría un int y devolver una cadena, al igual que ...

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

Pero, ya que la pregunta original llamada para conocer el valor de la lista original y es el recuento, Acabo de utilizar un número entero para clave mi agrupación entera para simplificar mi ejemplo.

+1

+1. esto es muy elegante para contar la ocurrencia de cada elemento distinto. –

+0

¿Qué pasa con list.FindAll? – CodeFusionMobile

+0

FindAll devuelve una lista de elementos de la lista original que coinciden con un predicado, por lo que tendría que hacerlo una vez para cada elemento único para encontrar el recuento de ese elemento. –

-1

Su lazo externo es un bucle sobre todas las palabras de la lista. No es necesario y le causará problemas. Quítalo y debería funcionar correctamente.

7

Puede hacer algo como esto para contar de una lista de cosas.

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

Contar un solo 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: Me tomó un tiempo para darse cuenta de que getMethods() era sólo su lista de cosas. :) –

+0

Sí, pensé en eso y decidí hacerlo más legible. gracias, aunque leí mal la pregunta. Dice contar "todo el elemento" .. ooops. Esto aún debería ser lo suficientemente útil. –

+0

@StanR. - Esta solución funciona para mi problema. Sin embargo, ¿hay un método en la lista donde puedo contar la ocurrencia mayor o igual que en palabras? Estoy usando el tipo "int" en lugar de "cadena". –

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

Esto está tomado de uno de los ejemplos en el LINQPad

Cuestiones relacionadas