LINQ com groupby e count

Isso é bem simples, mas estou perdendo: dado esse tipo de dataset:

UserInfo(name, metric, day, other_metric) 

e este dataset de amostra:

 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 

Gostaria de recuperar uma tabela que lista métricas em ordem (0,1,2,3 ..) com o número total de vezes que a contagem ocorre. Então, a partir desse set você acabaria com:

 0 3 1 2 2 2 3 1 

Eu estou lutando com a syntax LINQ, mas estou preso em onde colocar um groupby e contar …. qualquer ajuda?

POST Edit: Nunca consegui que as respostas postadas funcionassem, pois elas sempre retornavam um registro com o número de contagens diferentes. No entanto, consegui reunir um exemplo de LINQ to SQL que funcionou:

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

Esse resultado me deu um conjunto ordenado de registros com “métricas” e o número de usuários associados a cada um deles. Eu sou claramente novo no LINQ em geral e, para meu olho destreinado, essa abordagem parece muito semelhante à abordagem LINQ pura, mas me deu uma resposta diferente.

Depois de chamar GroupBy , você obtém uma série de grupos IEnumerable , onde cada Agrupamento em si expõe a Key usada para criar o grupo e também é um IEnumerable de quaisquer itens em seu dataset original. Você só precisa chamar Count() nesse Agrupamento para obter o 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 foi uma resposta rápida e rápida, mas estou tendo um problema com a primeira linha, especificamente “data.groupby (info => info.metric)”

Eu estou supondo que você já tem uma lista / array de alguma class que se parece com

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

Quando você faz o data.GroupBy(x => x.metric) , significa “para cada elemento x no IEnumerable definido por data , calcule seu .metric , agrupe todos os elementos com a mesma métrica em um Grouping e retorne um IEnumerable de todos os grupos resultantes, dado o seu exemplo de dataset 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 

resultaria no seguinte resultado após o groupby:

 (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] 

Supondo que userInfoList seja uma List :

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

A function lambda para GroupBy() , n => n.metric significa que obterá a metric campo de cada object UserInfo encontrado. O tipo de n depende do contexto, na primeira ocorrência é do tipo UserInfo , porque a lista contém objects UserInfo . Na segunda ocorrência n é do tipo Grouping , pois agora é uma lista de objects Grouping .

Grouping s tem methods de extensão como .Count() , .Key() e praticamente qualquer outra coisa que você esperaria. Assim como você verificaria .Lenght Em uma string , você pode verificar .Count() em um grupo.

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