LINQ 与 groupby 和计数
Posted
技术标签:
【中文标题】LINQ 与 groupby 和计数【英文标题】:LINQ with groupby and count 【发布时间】:2011-11-09 06:52:29 【问题描述】:这很简单,但我不知所措: 鉴于这种类型的数据集:
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
我想检索一个按顺序(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 方法非常相似,但却给了我不同的答案。
【问题讨论】:
是的,我有,但吉米的解释对我帮助更大。然而,我始终无法让他的榜样发挥作用,但它确实将我引向了一个新的方向。 @Jimmy 使用 LINQ 表达式的函数语法而不是标准的 LINQ 查询语法,此外他决定展示这些函数的立即执行而不是延迟执行格式。对于一个会感到困惑的新人。不知道他为什么这么做。 【参考方案1】:调用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=>info.metric)”
我假设您已经有一些 class
的列表/数组,看起来像
class UserInfo
string name;
int metric;
..etc..
...
List<UserInfo> data = ..... ;
当你做data.GroupBy(x => x.metric)
时,它的意思是“对于data
定义的IEnumerable中的每个元素x
,计算它是.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]
【讨论】:
这是一个非常快速的回复,但我在第一行遇到了一些问题,特别是“data.groupby(info=>info.metric)”。显然“数据”是当前数据集,但“info.metric”代表什么?类定义? "info.metric" 将是您在问题中提到的 UserInfo 类的指标属性/字段。 谢谢,但实际上这似乎给了我一个值 - 即不同指标计数的总数。在这个例子中,我得到“metrics 4”,这表明我有多少不同的计数。 哇。你完全解释了分组!仅此一项就值得发帖……我仍然得到“指标 4”的结果,但谢谢! 这个答案的开头,“在调用 GroupBy 之后,你会得到一系列组 IEnumerable假设userInfoList
是List<UserInfo>
:
var groups = userInfoList.GroupBy(n => n.metric)
.Select(n => new
MetricName = n.Key,
MetricCount = n.Count()
)
.OrderBy(n => n.MetricName);
GroupBy()
、n => n.metric
的 lambda 函数意味着它将从遇到的每个 UserInfo
对象中获取字段 metric
。 n
的类型取决于上下文,在第一次出现时其类型为 UserInfo
,因为列表包含 UserInfo
对象。在第二次出现时,n
的类型为 Grouping
,因为现在它是 Grouping
对象的列表。
Grouping
s 具有扩展方法,例如 .Count()
、.Key()
以及几乎所有您期望的其他方法。就像您在 string
上检查 .Length
一样,您可以在组上检查 .Count()
。
【讨论】:
【参考方案3】:userInfos.GroupBy(userInfo => userInfo.metric)
.OrderBy(group => group.Key)
.Select(group => Tuple.Create(group.Key, group.Count()));
【讨论】:
以上是关于LINQ 与 groupby 和计数的主要内容,如果未能解决你的问题,请参考以下文章
Visual Web Developer 2008 不会从 Linq 自动生成类