Linq: 对列表进行分组、排序并获取前x个值?

4

我有一个列表:

姓名   国家       值
John  Ireland    100
Mary  UK         200
Peter Germany    300
Bob   UK         100
Pat   France     400

我需要按国家分组,然后按值的总和降序排序,最后取前 X 个值。

例如,List.TopX(3) 将返回以下结果:

France  400
UK      300
Germany 300

1
不是作业。您可以从我的个人资料中看到我已经37岁了。 - Andrew White
1
我个人并没有形成那种观点,因此我认为很值得快速回答。我希望你能够获得LINQPad,并阅读《C#深入》(如果你想让所有内容都有意义)或者《LINQ实战》(如果你想让LINQ到XML或LINQ到SQL有意义)。不过,你应该尽快进行跟进,以使问题得到最大的价值 - 人们通常在回答后会留下一段时间,对问题进行反应 - 这并不总是关于一个编译良好的示例答案和抓住某些神秘目标的分数。底线 - 大多数人并不持有如此愤世嫉俗的态度。 - Ruben Bartelink
2个回答

13

周末回答这个问题时,我没有时间完全评论它,但我有一些想说的话。首先,我同意评论者的看法,这听起来非常像作业。如果你已经尝试过某些东西并且遇到了问题,我希望听到你的问题所在。Stack Overflow是关于专业人士互相帮助解决特定问题的地方,当他们尝试过所有方法仍然不能完全解决问题。这个问题有一个简单的回答(对于那些花时间阅读关于LINQ的文档的人来说)。我故意使用链式lambda符号而不是LINQ表达式,以指出回答实际上是问题的直接翻译:

var results = list.GroupBy(e => e.Country) // group the list by country
    .OrderByDescending(                 // then sort by the summed values DESC
        g => g.Sum(e => e.Value))  
    .Take(n)                            // then take the top X values
    .Select(                            // e.g. List.TopX(3) would return...
        r => new {Country = r.Key, Sum = r.Sum(e => e.Value)}); 

如果我实际上是为工作而做这件事,我会使用以下符号:

var results = from e in list
              group e.Value by e.Country into g
              let sum = g.Sum()
              orderby sum descending
              select new {g.Key, sum};
results = results.Take(n);

1
我在Stackoverflow的使命声明中没有看到它只是为专业人士而设立的。我是一个业余程序员,正在努力掌握Linq技术。如果问题听起来像作业,您没有义务回答它们。不过,我很感激您的回答。 - Andrew White
6
@安德鲁:你说得对。最近我了解了更多关于StackOverflow创立原则的知识,而我正在努力使自己更加接近它们。感谢您的反馈,抱歉之前表现得有些刻薄。 - StriplingWarrior

3
var all = from item in list
group item by item.Country into byCountry
let count = byCountry.Sum(element=>element.Value)
orderby count descending
select byCountry.Key, count

var justTop = all.Take(3);

虽然没有输入编译器,但这应该是简单的部分-下载LINQPad,在http://dimecasts.net上查看LINQPad教程,就可以解决问题:P


1
@Mitch Wheat:谢谢。我认为一个未经测试的答案是对于仍然似乎是作业或研究而言的适当回应。如果OP有真正需要解决问题但却遇到困难,我认为这个答案还是有些用处的。现在它给出了表达式语法而不是扩展链接语法,因此有足够的区别。你想让我删除它吗?理想情况下,我们的OP会介入并告诉我们什么是有效的。 - Ruben Bartelink
1
考虑到问题的质量较差,我认为这是一个完全合理的答案(在编辑后)。特别是关于LINQPad的部分。留在这里就好了。 - StriplingWarrior
@StriplingWarrior:谢谢(还有+1的赞!)(同时也+1给你最新回答的修订版)! - Ruben Bartelink
3
我很确定这个问题并不是“低质量”的。数据已经被呈现出来了,算法也被解释了,预期的答案也被产生了…… - Andrew White
1
确实,这个问题的某些方面比你在这里找到的很多东西要好得多。我的主要担忧是,你似乎希望我们替你思考。就我所知,解决方案只是将要求转换为LINQ的问题。从专业角度来看,SO用户想知道你遇到了什么陷阱,阻止你自己解决它。 - StriplingWarrior

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接