2011-09-02 78 views
145

这是很简单,但我很茫然: 鉴于这种类型的数据集:LINQ与GROUPBY和计数

UserInfo(name, metric, day, other_metric) 

和这个样本数据集:

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 

我d想要检索一个表,按照(0,1,2,3 ..)的顺序列出指标的总数并记录计数。所以从这个集合你最终用:

0 3  
1 2  
2 2  
3 1 

我与LINQ语法拼杀,但我被困在那里放了GROUPBY和计数.... 任何帮助?

POST编辑:我从来没有能够得到发布的答案工作,因为他们总是返回一个记录与不同计数的数量。但是我能够把一个LINQ to SQL的例子做了工作:

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

这个结果给了我一组有序的记录与“指标”,并与各相关用户的数量。对于LINQ来说,我显然是新手,对于未经训练的人来说,这种方法看起来与纯LINQ方法非常相似,但给了我一个不同的答案。

+0

是的,但是吉米的解释对我更有帮助。然而,我从来没有得到他的榜样工作,但它确实带领我迈向一个新的方向。 – Gio

回答

254

调用GroupBy后,你会得到一个系列组IEnumerable<Grouping>,其中每个分组本身暴露了用于创建组Key的,也就是不管项目是在原始数据集的IEnumerable<T>。您只需在该分组上拨打Count()即可获得小计。

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


这是一个出色的快速回复,但我有一个有点问题的第一行,特别是 “data.groupby(资讯=> info.metric)”

一些 class,看起来像

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

我假设你已经有一个列表/阵列

当你data.GroupBy(x => x.metric),它的意思是“由data定义的每个元素在x了IEnumerable,计算它的.metric,然后组都具有相同的度量中的元素变成Grouping并返回所有所得组的IEnumerable。鉴于

<DATA>   | 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 

您的示例数据集中,将导致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] 
+0

这是一个非常快速的回复,但我在第一行遇到了一些问题,特别是“data.groupby(info => info.metric)”。显然'数据'是当前的数据集,但'info.metric'代表什么?类定义? – Gio

+0

“info.metric”将是您在问题中提到的UserInfo类的度量属性/字段。 –

+1

非常感谢,但实际上这似乎给了我一个单一的值 - 即不同度量计数的总数。在这个例子中,我得到了“度量4”,它向我表明了我有多少不同的计数。 – Gio

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

假设userInfoListList<UserInfo>

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

lambda函数对于GroupBy()n => n.metric mea ns,它将从每遇到UserInfo对象获得字段metricn的类型取决于上下文,首次出现时它的类型为UserInfo,因为该列表包含UserInfo对象。第二次出现n的类型为Grouping,因为现在它是一个Grouping对象的列表。

Grouping s有扩展方法,如.Count(),.Key()和几乎任何你所期望的。就像您在string上检查.Lenght一样,您可以在组上检查.Count()