Почему я не могу отсортировать по экземплярам моего объекта? - PullRequest
2 голосов
/ 10 апреля 2019

Я пытаюсь отсортировать объект, players, по среднему количеству очков каждого игрока, а затем вернуть трех лучших игроков в массиве.

Я получаю sort is not a function, что заставляет меня думать, что я не вызываю его с правильным типом данных (я пытаюсь отсортировать по числу, называемому «средним»).

Я пытался написать функцию несколькими способами, надеясь получить доступ к свойству average player в players, но продолжаю получать sort is not a function.

Ниже приведен мой код (исключая функции, которые уже работают):

class Player {
    constructor(player_id, score) {
        this.player_id = player_id;
        this.scores = [score];
        this.total = score;
        this.average = this.averageScore();
    }

    averageScore() {
        return this.scores.length ? this.total / this.scores.length : 0;
    }

};

class LeaderBoard {

    constructor() {
        this.players = {};
    }

    top = (num_players) => {
      var sorted = this.players.sort((a, b) => (a.average > b.average) ? 1 : -1)
      return sorted.slice(0, num_players);
    }

};

Я бы хотел, чтобы он возвращал массив индексов от 0 до num_players после того, как они отсортированы по их средним, но вместо этого я получаю sort is not a function - что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 10 апреля 2019

Похоже, у вас есть объект this.players с ключами в качестве имен игроков.И вы хотите получить объект в результате.Если это так, используйте Objects.keys, чтобы получить первые 3, а затем используйте reduce(), чтобы преобразовать обратно в объект.

var sorted = Object.entries(this.players)
                           .sort(([,v1], [,v2]) => v1.average - v2.average)
                           .slice(0,num_players)
                           .reduce((ac,[k]) => ({...ac,[k]:this.players[k]}),{})
1 голос
/ 10 апреля 2019

Вы хотите получить players в массиве ... Object.values ​​(this.players) сделает это

тогда вы можете сортировать и нарезать

В одной строке кода это будет

top = (num_players) => Object.values(this.players)
                       .sort((a, b) => (a.average - b.average))
                       .slice(0, num_players);

в качестве бонуса: я бы объявил игрока как

class Player {
    constructor(player_id, score) {
        this.player_id = player_id;
        this.scores = [score];
        this.total = score;
    }

    get average() {
        return this.scores.length ? this.total / this.scores.length : 0;
    }

};

make average свойство a getter - должно работать так же, как ваш текущий код

вот исполняемый фрагмент, объединяющий мой предыдущий ответ с этим

class Player {
    constructor(player_id, score) {
        this.player_id = player_id;
        this.scores = [score];
        this.total = score;
    }

    addScore(score) {
        this.total += score;
        this.scores.push(score);
        return score;
    }

    get average() {
        return this.scores.length ? this.total / this.scores.length : 0;
    }

    resetScore() {
        this.scores = [];
        this.score = 0;
    }

};
class LeaderBoard {
    constructor() {
        this.players = {};
    }
    addScore(player_id, score) {
        if (!this.players[player_id]) {
            this.players[player_id] = new Player(player_id, score);
        } else {
            this.players[player_id].addScore(score);
        }
        return this.players[player_id].average.toFixed(1);
    }
    top = (num_players) => Object.values(this.players)
                           .sort((a, b) => (a.average - b.average))
                           .slice(0, num_players);

    topids = (num_players) => Object.values(this.players)
                           .sort((a, b) => (a.average - b.average))
                           .map(({player_id}) => player_id)
                           .slice(0, num_players);
};
let x = new LeaderBoard();
x.addScore(1, 8);
x.addScore(2, 3);
x.addScore(3, 1);
x.addScore(4, 4);
console.log(x.topids(2));
console.log(x.top(2));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...