在Javascript中按值分配给出一系列目标的得分

时间:2017-07-05 03:47:14

标签: javascript arrays sorting

/*
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);

1 个答案:

答案 0 :(得分:0)

我相信您当前的代码i + numTies实际应该是i + numTies + 1,因为数组索引(i)从零开始,但排名从1开始(对于测试数据)这个问题没有引起问题,因为唯一没有绑定的项目是最后一个。)

但您根本不需要numTies变量,因为非绑定元素的排名始终与其在数组中的位置(+1)相同。

此外,执行第一项的for循环之前的行如果数组为空则会出错,因此您应该测试它。并使用var声明i

&#13;
&#13;
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);
&#13;
&#13;
&#13;

如果从0开始循环而不是1,并测试循环内的第一个元素,那么您可以选择重构代码以使用数组迭代函数而不是for循环 - 执行会比较慢,但(可以说)更容易阅读。

对于多样性,我使用了三元运算符而不是if/else

&#13;
&#13;
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);
&#13;
&#13;
&#13;