问题描述
我得到了一个按得分排序的球队名单
MySplitter
现在,我将根据这些球队的得分对其进行排名。
SplitterLayout
结果看起来像这样
Team G,score:7
Team A,score:5
Team X,score:4
Team Y,score:4
Team T,score:3
Team K,score:3
Team P,score:2
Team L,score:2
Team E,score:1
Team R,score:1
Team O,score:1
Team Q,score:1
但是我希望队伍看起来像这样
public static void AddRankByscore(List<TeamExtended> teams)
{
if (teams == null) return;
var rank = 1;
foreach (var team in teams)
{
team.Rank= $"{rank}";
rank++;
}
}
我该怎么做?如果球队得分相同,我必须跳过一些排名。
解决方法
您只需添加一个检查,看看分数是否等于我们检查的lastscore
。如果是这样,根据equalplacing
的变化,我们根据同一地点的球队数量开始计算lastscore
变量以提高得分。
// Last score that team had.
int lastscore = 0;
// Amount of placings on the same spot.
int equalplacing = 1;
// Current rank.
int rank = 0;
foreach (var team in teams) {
// Check if current team score is not equal to the last team score.
if (team.Score != lastscore) {
rank += equalplacing;
equalplacing = 1;
}
else {
equalplacing++;
}
team.Rank = rank;
lastscore = team.Score;
}
要确保排名有效,您需要按照得分从小到大的顺序对列表进行排序。您可以使用Linq和.OrderByDescending()
来做到这一点。
teams = teams.OrderByDescending(o=>o.Score).ToList();
,
通过Team
属性对Score
对象进行分组和排序,然后将排名计数器增加每个组的计数而不是1
来获得所需的输出。
LINQ
示例:
public static void AddRankByScore(List<TeamExtended> teams) => teams
.GroupBy(x => x.Score)
.OrderByDescending(x => x.Key)
.Aggregate(1,(r,g) =>
{
g.Aggregate(0,(_,t) => t.Rank = r);
r += g.Count();
return r;
});
foreach
示例:
public static void AddRankByScore(List<TeamExtended> teams)
{
var r = 1;
foreach (var g in teams
.GroupBy(x => x.Score)
.OrderByDescending(x => x.Key))
{
foreach (var t in g)
t.Rank = r;
r += g.Count();
}
}
其中每一个都如下修改给定列表(Rank
)的teams
属性:
G,7,1
A,5,2
X,4,3
Y,3
T,3,5
K,5
P,2,7
L,7
E,1,9
R,9
O,9
Q,9