:)
var results =
from kvp in source
group kvp by kvp.Key.ToUpper() into g
select new
{
Group = g,
Max = g.Max(kvp => kvp.Value),
Total = g.Sum(kvp => kvp.Value)
} into ag
from x in ag.Group //SelectMany
where x.Value != ag.Max
//for the update to the question - note: possibly ambiguous
let correct = ag.Group.Where(y => y.Value == ag.Max).First().Key
select new
{
Key = x.Key,
Max = ag.Max,
Total = ag.Total,
Correct = correct
};
我有点喜欢这个问题,因为做出答案所需的所有小部分(有些很少使用)。
Max = g.Max(kvp => kvp.Value),
Total = g.Sum(kvp => kvp.Value)
对一个组执行多个聚合很简单,但如果您不知道如何操作,则具有挑战性。
select a into b
该子句获取之前发生的所有内容并开始使用目标的新查询。没有它,我必须开始一个新的查询,如下所示:
var A = ... select a
var B = from b in A
重要的是要注意select into
子句删除kvp
and g
从范围来看。
from b in source
from a in b.A //SelectMany
子集合的这种“解包”将我对 b 的查询变成了对 a 的查询。与默认的 Enumerable.SelectMany 重载不同,它离开父级 (b
) 在适用范围。
where x.Value != ag.Max
将孩子的财产与父母的财产进行比较?愉快。记住突破很重要where
任何时候你想过滤,即使你只是分组(没有HAVING
).