为什么不能按对象实例排序?

时间:2019-04-10 03:16:57

标签: javascript sorting

我正在尝试按照每个玩家的平均得分对players对象进行排序-然后返回数组中排名前三的玩家。

我得到sort is not a function,这让我觉得我没有在适当的数据类型上调用它(我正在尝试按一个称为“平均值”的数字进行排序)。

我试图以多种方式编写该函数,希望访问averageplayer的{​​{1}}的{​​{1}}属性,但一直得到players。 / p>

下面是我的代码(不包括已经起作用的功能):

sort is not a function

我希望它按平均值对索引0到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); } }; 进行排序后返回一个数组,但我却得到num_players-我在做什么错?

2 个答案:

答案 0 :(得分:2)

似乎您拥有对象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 :(得分:1)

您将希望将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;
    }

};

average属性设为 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));