获取排名的 linq 问题
Posted
技术标签:
【中文标题】获取排名的 linq 问题【英文标题】:linq issue to get a ranking 【发布时间】:2021-06-05 07:37:58 【问题描述】:我很难获得用户在列表中的排名。
我的列表如下所示:
User | Score |
---|---|
1 | 10 |
2 | 10 |
1 | 5 |
3 | 5 |
2 | 40 |
1 | 10 |
我尝试获取用户 3 的排名。
为此,我使用按用户 ID 分组的第一个 linq 请求。
然后我请求将分数(nbpoints)和 orderby 像这样降序求和:
用户 2 获得 50 分 用户 1 有 25 分 用户 3 获得 5 分
那么如何获取用户的排名呢?我用 select 尝试了索引,但它在排序之前使用了索引。
我的要求如下:
MyScoreRankObject = users.Select((u, index) =>
return new StatResultDto
ActualScore = u.Sum(s => s.NbPoints),
Index = u.Index
;
).OrderByDescending(s => s.ActualScore).Where(u => u.Id ==3).FirstOrDefault();
我怎样才能获得排名?
我试图得到:
对用户 3 的请求给了我对象:
new StatResultDto
ActualScore = u.Sum(s => s.NbPoints),
Index = u.Index // Gives the ranking
;
谢谢,
【问题讨论】:
这能回答你的问题吗? How to get the index of an item in a list in a single step? 【参考方案1】:我为其他苦苦挣扎的人找到了解决方案。不确定最好的一个。如果你有更好的我接受。我在 order by 之后添加了此代码。
.Select((u, index) =>
u.Rank = index + 1;
return u;
)
最终解决方案:
MyScoreRankObject = users.Select((u) =>
return new StatResultDto
ActualScore = u.Sum(s => s.NbPoints)
;
).OrderByDescending(s => s.ActualScore).Select((u, index) =>
u.Rank = index + 1;
return u;
).Where(u => u.Id ==3).FirstOrDefault();
【讨论】:
您无需再执行最后两个步骤Select & Where
。查看My answer了解更多详情。【参考方案2】:
Demo on dotnetfiddle
其实你只是GroupBy
然后OrderByDescending
。
var groupByandSortedData = myData.GroupBy(r => r.UserId)
.Select(g => new User = g.Key, ActualScore = g.Sum(s => s.NbPoints) )
.OrderByDescending(p => p.ActualScore);
最后,您可以通过ranking
使用以下3 种方式获取您的数据:
var ranking = 3;
Console.WriteLine(groupByandSortedData.Skip(2).FirstOrDefault());
Console.WriteLine(groupByandSortedData.ElementAtOrDefault(ranking-1)); // due to index starting from 0
Console.WriteLine(groupByandSortedData.ToList()[ranking-1]);
输出
User = 3, ActualScore = 5
User = 3, ActualScore = 5
User = 3, ActualScore = 5
在性能方面
我更喜欢第一种和第二种方式而不是第三种方式。因为最后一种方法已经执行了所有数据并加载到内存中。
【讨论】:
感谢您的回复,但我不想获得第三个。我想知道用户3是哪个排名。以上是关于获取排名的 linq 问题的主要内容,如果未能解决你的问题,请参考以下文章