/*
Given an array of objects: ID|userName|totalScore|competitionRank,
number ID
string userName
number totalScore
number competitionRank
all competitionRanks are set to NULL
give each score a ranking in descending order
*/
我目前不确定这是否会通过所有边缘情况。另外,这似乎是我能做到的最快的,任何改进方面的帮助都会很棒。它通过了我能想到的测试用例。任何帮助将不胜感激。
//Initialize data structure
var playerScores = [
{
"ID": 1,
"userName": "person1",
"totalScore": 230,
"competitionRank": null
},{
"ID": 2,
"userName": "person2",
"totalScore": 220,
"competitionRank": null
},{
"ID":3,
"userName": "person3",
"totalScore": 250,
"competitionRank": null
},{
"ID":4,
"userName": "person4",
"totalScore": 230,
"competitionRank": null
},{
"ID": 5,
"userName": "person5",
"totalScore": 250,
"competitionRank": null
}
];
playerScores.sort(function(a,b){
return b.totalScore - a.totalScore;
});
var numTies = 0;
playerScores[0].rank = 1;
for (i = 1; i < playerScores.length; i++){
if (playerScores[i].totalScore === playerScores[i-1].totalScore){
numTies++;
playerScores[i].rank = playerScores[i-1].rank;
}
else{
playerScores[i].rank = i+numTies;
numTies = 0;
}
}
console.log(playerScores);
最佳答案
我相信您当前的代码i + numTies
实际上应该是i + numTies + 1
,因为数组索引(i
)是从零开始,但排名从 1 开始(对于问题中的测试数据,这不会导致问题,因为唯一的非绑定(bind)项是最后一个)。
但是您根本不需要 numTies
变量,因为非绑定(bind)元素的排名始终与其在数组中的位置相同 (+1)。
此外,如果数组为空,执行第一项的 for
循环之前的行将给出错误,因此您应该对此进行测试。并使用 var
声明 i
:
var playerScores = [
{ "ID": 1, "userName": "person1", "totalScore": 230, "competitionRank": null },
{ "ID": 2, "userName": "person2", "totalScore": 220, "competitionRank": null },
{ "ID": 3, "userName": "person3", "totalScore": 250, "competitionRank": null },
{ "ID": 4, "userName": "person4", "totalScore": 230, "competitionRank": null },
{ "ID": 5, "userName": "person5", "totalScore": 250, "competitionRank": null }
];
playerScores.sort(function(a,b){ return b.totalScore - a.totalScore; });
if (playerScores[0]) playerScores[0].rank = 1;
for (var i = 1; i < playerScores.length; i++) {
if (playerScores[i].totalScore === playerScores[i-1].totalScore) {
playerScores[i].rank = playerScores[i-1].rank;
} else {
playerScores[i].rank = i + 1;
}
}
console.log(playerScores);
如果您从 0 而不是 1 开始循环,并测试循环内的第一个元素,那么您可以选择重构代码以使用数组迭代函数而不是 for
循环 - 执行速度较慢,但(可以说)更易于阅读。
为了多样化,我使用了三元运算符而不是 if/else
:
var playerScores = [
{ "ID": 1, "userName": "person1", "totalScore": 230, "competitionRank": null },
{ "ID": 2, "userName": "person2", "totalScore": 220, "competitionRank": null },
{ "ID": 3, "userName": "person3", "totalScore": 250, "competitionRank": null },
{ "ID": 4, "userName": "person4", "totalScore": 230, "competitionRank": null },
{ "ID": 5, "userName": "person5", "totalScore": 250, "competitionRank": null }
];
playerScores.sort(function(a,b){ return b.totalScore - a.totalScore; });
playerScores.forEach(function(player, i, arr) {
player.rank = i === 0 || player.totalScore != arr[i-1].totalScore
? i + 1
: arr[i-1].rank;
});
console.log(playerScores);
关于javascript - 在 Javascript 中按值给出一系列目标的排名分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44916692/