I have two objects in javascript:
Users:
{ userId: 'id1', score: 100 },
{ userId: 'id2', score: 3 },
{ userId: 'id3', score: 2 },
{ userId: 'id4', score: 1 }
and minimumRequirements:
{ firstPlaceMinScore: 100, secondPlaceMinScore: 50, thirdPlaceMinScore: 10 }
I am trying to create a leaderboard where users should be sorted by their places if they met the requiremenents for minimum points. For example
Group1:
{ userId: 'id1', score: 3 },
{ userId: 'id2', score: 2 },
{ userId: 'id3', score: 1 }
should return:
{ userId: 'id1', place: 4 },
{ userId: 'id2', place: 5 },
{ userId: 'id3', place: 6 }
group2:
{ userId: 'id1', score: 55 },
{ userId: 'id2', score: 30 },
{ userId: 'id3', score: 52 },
{ userId: 'id4', score: 10 },
{ userId: 'id5', score: 1 }
should return:
{ userId: 'id1', place: 2 },
{ userId: 'id3', place: 3 },
{ userId: 'id2', place: 4 },
{ userId: 'id4', place: 5 },
{ userId: 'id5', place: 6 }
I have written the following function but i can’t get around the filtering of leaders part, they are messing up the count:
function getLeaderboard(users, minScores) {
let leaderboard = [];
let formattedMinScores = Object.values(minScores);
const sortedUsers = users.sort((a, b) => b.score - a.score);
loop1: for (let i = 0; i < sortedUsers.length; i++) {
let currentPlace = i + 1;
loop2: for (let j = 0; j < formattedMinScores.length; j++) {
++currentPlace;
if (sortedUsers[i].score >= formattedMinScores[j]) {
currentPlace = j + 1;
break loop2;
}
}
leaderboard.push({
place: currentPlace,
userId: sortedUsers[i].userId
});
}
console.log(leaderboard);
return leaderboard;
}
2
Answers
Here is a solution: you start at place 0 and for each user, you increment the place by 1. You also increment it by the number of minimum required scores that are above the user’s score (
s > user.score
), as long as those minimum score are not for a place above the current place (i+1 >= currentPlace
)You can sort the scores first then iterate through the positional mins.
Note: I changed your placement min object into an indexable array.