Linq - 每组的最高值
如何使用 Linq 从每个组中选择最高值
当我有如下代码段时,
var teams = new Team[]
{
new Team{PlayerName="Ricky",TeamName="Australia", PlayerScore=234},
new Team{PlayerName="Hussy",TeamName="Australia", PlayerScore=134},
new Team{PlayerName="Clark",TeamName="Australia", PlayerScore=334},
new Team{PlayerName="Sankakara",TeamName="SriLanka", PlayerScore=34},
new Team{PlayerName="Udana",TeamName="SriLanka", PlayerScore=56},
new Team{PlayerName="Jayasurya",TeamName="SriLanka", PlayerScore=433},
new Team{PlayerName="Flintop",TeamName="England", PlayerScore=111},
new Team{PlayerName="Hamirson",TeamName="England", PlayerScore=13},
new Team{PlayerName="Colingwood",TeamName="England", PlayerScore=421}
};
:所需结果:
Team Name Player Name Score Srilanka Jayasurya 433 England colingwood 421 Australia Clark 334
How can I employ Linq to select Top value from each group
when I have a code segment like :
var teams = new Team[]
{
new Team{PlayerName="Ricky",TeamName="Australia", PlayerScore=234},
new Team{PlayerName="Hussy",TeamName="Australia", PlayerScore=134},
new Team{PlayerName="Clark",TeamName="Australia", PlayerScore=334},
new Team{PlayerName="Sankakara",TeamName="SriLanka", PlayerScore=34},
new Team{PlayerName="Udana",TeamName="SriLanka", PlayerScore=56},
new Team{PlayerName="Jayasurya",TeamName="SriLanka", PlayerScore=433},
new Team{PlayerName="Flintop",TeamName="England", PlayerScore=111},
new Team{PlayerName="Hamirson",TeamName="England", PlayerScore=13},
new Team{PlayerName="Colingwood",TeamName="England", PlayerScore=421}
};
Desired Result :
Team Name Player Name Score Srilanka Jayasurya 433 England colingwood 421 Australia Clark 334
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我的答案与 Yuriy 的类似,但使用
MaxBy
来自 MoreLINQ,这不需要比较由 ints 完成:请注意,我已将类型名称从“团队”更改为“玩家”,因为我认为这更有意义 - 您不是从一组团队开始,而是从一组玩家开始。
My answer is similar to Yuriy's, but using
MaxBy
from MoreLINQ, which doesn't require the comparison to be done by ints:Note that I've changed the type name from "Team" to "Player" as I believe it makes more sense - you don't start off with a collection of teams, you start off with a collection of players.
以下代码获取所需的值:
它需要我今天早些时候编写的以下扩展:
以下代码在没有扩展的情况下获取答案,但速度稍慢:
The following code gets the desired value:
It requires the following extension that I wrote earlier today:
The following gets the answer without the extension, but is slightly slower:
这将要求您按团队名称分组,然后选择最高分数。
唯一棘手的部分是找到相应的球员,但这还不错。只需选择得分最高的玩家即可。当然,如果可能有多个玩家具有相同的分数,请使用如下所示的 First() 函数而不是 Single() 函数来执行此操作。
仅供参考 - 我确实针对您的数据运行了这段代码并且它起作用了(在我修复了那个之后,出现了一些数据错误)。
This will require you to group by team name then select the max score.
The only tricky part is getting the corresponding player, but its not too bad. Just select the player with the max score. Of coarse, if its possible for more than one player to have identical scores do this using the First() function as shown below rather than the Single() function.
FYI - I did run this code against your data and it worked (after I fixed that one, little data mistake).
我会使用这个 Lambda 表达式:
I would use this Lambda expression:
The Lame Duck 提出的实现很棒,但需要对分组集进行两次 O(n) 遍历才能找出最大值。计算一次 MaxScore 然后重复使用将会受益匪浅。这就是 SelectMany(C# 中的 let 关键字)派上用场的地方。这是优化后的查询:
The implementation proposed by The Lame Duck is great, but requires two O(n) passes over the grouped set to figure out the Max. It would benefit from calculating MaxScore once and then reusing. This is where SelectMany (the let keyword in C#) comes in handy. Here is the optimized query:
我建议您首先在 IEnumerbale 类上实现一个名为 Top 的扩展方法
例如:
那么你可以这样写:
teams.GroupBy(team => team.TeamName).Top(team => team.PlayerScore, 1)。
可能需要进行一些细微的修改才能编译。
I would suggest you first implement an extension method on the IEnumerbale class called Top
For example:
Then you can write:
teams.GroupBy(team => team.TeamName).Top(team => team.PlayerScore, 1).
There might be some slight modifications to make it compile.