LINQ con groupby y recuento

Esto es bastante simple, pero estoy perdido: dado este tipo de conjunto de datos:

UserInfo(name, metric, day, other_metric) 

y este conjunto de datos de muestra:

 joe 1 01/01/2011 5 jane 0 01/02/2011 9 john 2 01/03/2011 0 jim 3 01/04/2011 1 jean 1 01/05/2011 3 jill 2 01/06/2011 5 jeb 0 01/07/2011 3 jenn 0 01/08/2011 7 

Me gustaría recuperar una tabla que enumere las medidas en orden (0,1,2,3 ..) con el número total de veces que se produce el recuento. Entonces, de este conjunto terminarías con:

 0 3 1 2 2 2 3 1 

Estoy lidiando con la syntax de LINQ, pero estoy atascado en dónde poner un groupby y contar … ¿Alguna ayuda?

Edición de POST: nunca pude obtener las respuestas publicadas para trabajar, ya que siempre devolvieron un registro con la cantidad de conteos diferentes. Sin embargo, pude armar un ejemplo LINQ to SQL que funcionó:

  var pl = from r in info orderby r.metric group r by r.metric into grp select new { key = grp.Key, cnt = grp.Count()}; 

Este resultado me dio un conjunto ordenado de registros con ‘métricas’ y el número de usuarios asociados con cada uno. Soy claramente nuevo en LINQ en general y para mi ojo no entrenado este enfoque parece muy similar al enfoque puro de LINQ pero me dio una respuesta diferente.

Después de llamar a GroupBy , obtienes una serie de grupos IEnumerable , donde cada Agrupación expone la Key utilizada para crear el grupo y también es un IEnumerable de los elementos que estén en tu conjunto de datos original. Solo tiene que llamar a Count() en esa Agrupación para obtener el subtotal.

 foreach(var line in data.GroupBy(info => info.metric) .Select(group => new { Metric = group.Key, Count = group.Count() }) .OrderBy(x => x.Metric) { Console.WriteLine("{0} {1}", line.Metric, line.Count); } 

Esta fue una respuesta shinymente rápida, pero estoy teniendo un problema con la primera línea, específicamente “data.groupby (info => info.metric)”

Supongo que ya tienes una lista / array de alguna class que se parece a

 class UserInfo { string name; int metric; ..etc.. } ... List data = ..... ; 

Cuando haces data.GroupBy(x => x.metric) , significa “para cada elemento x en IEnumerable definido por data , calcula su .metric , luego agrupa todos los elementos con la misma métrica en una Grouping y devuelve un IEnumerable de todos los grupos resultantes. Dado su conjunto de datos de ejemplo de

   | Grouping Key (x=>x.metric) | joe 1 01/01/2011 5 | 1 jane 0 01/02/2011 9 | 0 john 2 01/03/2011 0 | 2 jim 3 01/04/2011 1 | 3 jean 1 01/05/2011 3 | 1 jill 2 01/06/2011 5 | 2 jeb 0 01/07/2011 3 | 0 jenn 0 01/08/2011 7 | 0 

daría como resultado el siguiente resultado después del grupo por:

 (Group 1): [joe 1 01/01/2011 5, jean 1 01/05/2011 3] (Group 0): [jane 0 01/02/2011 9, jeb 0 01/07/2011 3, jenn 0 01/08/2011 7] (Group 2): [john 2 01/03/2011 0, jill 2 01/06/2011 5] (Group 3): [jim 3 01/04/2011 1] 

Suponiendo que userInfoList es una List :

  var groups = userInfoList .GroupBy(n => n.metric) .Select(n => new { MetricName = n.Key, MetricCount = n.Count() } ) .OrderBy(n => n.MetricName); 

La función lambda para GroupBy() , n => n.metric significa que obtendrá la metric campo de cada objeto UserInfo encontrado. El tipo de n depende del contexto, en la primera aparición es de tipo UserInfo , porque la lista contiene objetos UserInfo . En la segunda aparición, n es de tipo Grouping , porque ahora es una lista de objetos Grouping .

Grouping tienen métodos de extensión como .Count() , .Key() y casi cualquier otra cosa que esperas. Del mismo modo que verificaría .Lenght en una string , puede verificar .Count() en un grupo.

 userInfos.GroupBy(userInfo => userInfo.metric) .OrderBy(group => group.Key) .Select(group => Tuple.Create(group.key, group.Count()));