I'm trying to sort an object, players by the average property of the instances of player within it, but I can't access make it work.
This is what the Players object looks like when I log it:
[ Player { player_id: 1, scores: [ 50 ], total: 50, average: 50 },
Player { player_id: 2, scores: [ 80, 70, 60 ], total: 210, average: 80 },
Player { player_id: 3, scores: [ 90, 85 ], total: 175, average: 90 } ]
But my sort function seems to fall flat - I think I need to add player somewhere to access the nested objects.
Here's that function code:
/* class definition excluded */
top = (num_players) =>
Object.values(this.players)
.sort((a, b) => (a.average - b.average))
.slice(0, num_players);
};
The test that's written for this function returns the following:
Top 3 [[object Object],[object Object],[object Object]] should equal [3, 2, 1]:
For context, here's the entire script with test cases, in case you'd like to try it out:
class Player {
constructor(player_id, score) {
this.player_id = player_id;
this.scores = [score];
this.total = score;
this.average = this.averageScore();
}
addScore(score) {
this.total += score;
this.scores.push(score);
return score;
}
averageScore() {
return this.scores.length ? this.total / this.scores.length : 0;
}
resetScore() {
this.scores = [];
this.score = 0;
}
};
class LeaderBoard {
constructor() {
this.players = {};
}
add_score(player_id, score) {
if (!this.players[player_id]) {
this.players[player_id] = new Player(player_id, score);
} else {
this.players[player_id].addScore(score);
}
var average = this.players[player_id].averageScore();
return average.toFixed(1);
}
top = (num_players) =>
// console.log(Object.values(this.players);
Object.values(this.players)
.sort((a, b) => (a.average - b.average))
.slice(0, num_players);
reset = (player_id) => {
this.players[player_id].resetScore();
}
};
// Test code here
function array_equals(a, b) {
if (a === b) return true;
if (a == null || b == null) return false;
if (a.length != b.length) return false;
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
var leader_board = new LeaderBoard()
leader_board.add_score(1, 50)
console.log(leader_board.add_score(2, 80) == 80)
console.log(leader_board.add_score(2, 70) == 75)
console.log(leader_board.add_score(2, 60) == 70)
console.log('Add score should return the average. test with 1 score')
console.log(leader_board.add_score(3, 90) == 90)
console.log('Add score should return the average. test with 2 scores')
console.log(leader_board.add_score(3, 85) == 87.5)
console.log('Top 3 [' + leader_board.top(3) + '] should equal [3, 2, 1]:')
console.log(array_equals(leader_board.top(3), [3, 2, 1]))
console.log('Top 2 [' + leader_board.top(2) + '] should equal [3, 2]:')
console.log(array_equals(leader_board.top(2), [3, 2]))
leader_board.reset(3)
console.log('After reset top 3 [' + leader_board.top(3) + '] should equal [2, 1, 3]')
console.log(array_equals(leader_board.top(3), [2, 1, 3]))
I'm expected that top will be able to sort the object of players by their average, then return them in an array from 0 to num_players but I'm not sorting successfully.
I haven't had any luck so far - How do I sort by the nested property?
leader_board.topreturns an array ofPlayers; your test expects an array ofplayer_ids. Which is correct?[object Object]when you use an object where a string is required. The problem isn't with sorting, it's with what you do with the result.