1

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?

7
  • What's the result you're currently getting? Commented Apr 11, 2019 at 1:24
  • Top 3 [[object Object],[object Object],[object Object]] should equal [3, 2, 1]: Commented Apr 11, 2019 at 1:28
  • leader_board.top returns an array of Players; your test expects an array of player_ids. Which is correct? Commented Apr 11, 2019 at 1:31
  • 1
    You see [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. Commented Apr 11, 2019 at 1:31
  • @Barmar what should I be doing with the object then? Commented Apr 11, 2019 at 1:33

1 Answer 1

3
  1. You're comparing the Player objects to the property of the object itself (player_id). A correct assert statement will look something like this:
console.log(array_equals(leader_board.top(3).map(p => p.player_id), [3, 2, 1]))
  1. You're sort function is in the wrong direction, simply switch it to be:
    sort((a, b) => (b.average - a.average))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.