Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何对包含表示分数的数组的多个对象进行排序?_Javascript - Fatal编程技术网

Javascript 如何对包含表示分数的数组的多个对象进行排序?

Javascript 如何对包含表示分数的数组的多个对象进行排序?,javascript,Javascript,给定如下对象数组: competitors = [{ name: "Alice", scores: [3,7,8,2,5] }, { name: "Bob", scores: [4,4,5,6,8] }, { name: "Carol", scores: [5,3,2,7,6] }]; 考虑到分数越低越好,我如何对它们进行排序(将它们排列为1-3级),以使优胜者是在每个指数中赢得最多比较的人 例如,对于Alice、Bob和Carol,Alice应

给定如下对象数组:

competitors = [{
    name: "Alice",
    scores: [3,7,8,2,5]
}, {
    name: "Bob",
    scores: [4,4,5,6,8]
}, {
    name: "Carol",
    scores: [5,3,2,7,6]
}];
考虑到分数越低越好,我如何对它们进行排序(将它们排列为1-3级),以使优胜者是在每个指数中赢得最多比较的人


例如,对于Alice、Bob和Carol,Alice应该赢,因为她赢了3场(3注:我更喜欢@Tibos答案,但这一场更简单

您可以使用排序函数():

功能getWins(竞争对手,竞争对手){
var得分=竞争对手得分;
var=0;
对于(变量i=0,n=scores.length;i得分[i]){
赢=假;
打破
}
}
}
如果(赢){
wins++;
}
}
回归胜利;
}
//根据竞争对手的获胜情况对其进行分类
竞争对手。排序(功能(a、b){
返回getWins(竞争对手,b)-getWins(竞争对手,a);
});

我发现它通常有助于将这样的大任务分解为几个阶段。我怀疑它是否有效,但它可能对您有用

首先:获取一个数组,其中包含每个竞争对手的结果:

function getScores() {
  return competitors.map(function (el) {
    return el.scores;
  });
}

var scores = getScores();
然后拉出单个游戏信息:

function getGames(scores) {
  var games = [];
  for (var i = 0, l = scores[0].length; i < l; i++) {
    games.push(scores.map(function (el) {
      return el[i];
    }));
  }
  return games;
}

var games = getGames(scores);
最后,更新每个竞争对手的结果

function applyWinners(winners) {
  winners.forEach(function (el, i) {
    var competitor = competitors[el];
    if (!competitor.results) competitor.results = [];
    competitor.results.push(i);
  });
}

applyWinners(winners);

console.log(competitors) // Alice wins [0, 3, 4], Carol wins [1, 2]

一个特殊的比较功能,用于计算下一级别的比赛胜负,可以实现以下功能:

function compareArray(a, b) {
    for (var i=0; i<a.length && i<b.length; i++)
        if (a[i] != b[i])
            return a[i] - b[i];
    return a.length-b.length;
}
function addWins(c) {
    var w = new Array(c.length);
    for (var i=0; i<numJudges; i++) {
        // if two players have scored equally, the first will win
        var l = 0;
        for (var j=1; j<c.length; j++)
            if (c[j].scores[i] < c[l].scores[i])
                l = j;
        w[l] = (w[l]||0)+1;
    }
    for (var i=0; i<c.length; i++)
        c[i].wins.push(w[i]||0);
}

for (var i=0; i<competitors.length; i++)
    competitors[i].wins = [];
competitors.sort(function(a, b) {
    var samelevel = competitors;
    do {
        var o = - compareArray(a.wins, b.wins)
        if (o != 0)
            return o;
        var len = samelevel.length;
        samelevel = samelevel.filter(function(c) {
            return compareArray(c.wins, a.wins) == 0;
        })
        addWins(samelevel);
    } while (samelevel.length < len);
    return - compareArray(a.wins, b.wins);       
});
函数比较数组(a,b){

对于(var i=0;iI会对项目的总和做些什么……这对你有什么启发吗?我已经在我的排名算法的前一步比较了分数总和。如果总和相等,我会继续进行这种平局打破(4个步骤中的最后一个)。如果两个竞争对手的分数相同(最低),会怎么样在某些游戏中得分?供将来参考:两对二比较不起作用,因为它允许循环排名:Alice:[1,2,3,4,5]Bob:[2,5,4,1,3]Carol:[5,1,2,3,4](由@DaveS给出的示例)如果我们比较两个竞争对手,那么就不会发生这种情况,因为在我的算法中,在这一点上,我处理的是每个竞争对手的分数为奇数。如果我们比较三个或更多的竞争对手,以及两个或更多的平局,那么我将不得不在平局的竞争对手集合上递归。如果竞争对手列表很长,这将变得非常缓慢,因为您将对每个比较执行(num scores*num competitors)操作…一个O(n^3)算法。@Pointy我不太关心速度,因为我实际上限制了分数数组的大小以及竞争对手的数量。这是排名算法的一部分,它通常会有奇数个分数(通常在3-11之间)和不超过20名竞争者。@Florent,这种类型(两对两比较)有一个问题是,在三个或三个以上的竞争对手中,可能会出现平局,如果将二乘二、二乘二和二乘二进行比较,就像在三方平局中一样,你可能会得到一个周期性的排名,如竞争对手#1>#2>#3>#1等。这看起来很有希望。当我有三个以上的竞争对手时,或者在ca中,我只需要重复几组竞争对手的胜负比如我的第二个例子,Dave、Eve和Frank,这是通过修改ApplyInners函数来实现递归的。
function findWinners(games) {
  return games.map(function (el) {
    return el.indexOf(Math.min.apply(null, el));
  });
}

var winners = findWinners(games);
function applyWinners(winners) {
  winners.forEach(function (el, i) {
    var competitor = competitors[el];
    if (!competitor.results) competitor.results = [];
    competitor.results.push(i);
  });
}

applyWinners(winners);

console.log(competitors) // Alice wins [0, 3, 4], Carol wins [1, 2]
function compareArray(a, b) {
    for (var i=0; i<a.length && i<b.length; i++)
        if (a[i] != b[i])
            return a[i] - b[i];
    return a.length-b.length;
}
function addWins(c) {
    var w = new Array(c.length);
    for (var i=0; i<numJudges; i++) {
        // if two players have scored equally, the first will win
        var l = 0;
        for (var j=1; j<c.length; j++)
            if (c[j].scores[i] < c[l].scores[i])
                l = j;
        w[l] = (w[l]||0)+1;
    }
    for (var i=0; i<c.length; i++)
        c[i].wins.push(w[i]||0);
}

for (var i=0; i<competitors.length; i++)
    competitors[i].wins = [];
competitors.sort(function(a, b) {
    var samelevel = competitors;
    do {
        var o = - compareArray(a.wins, b.wins)
        if (o != 0)
            return o;
        var len = samelevel.length;
        samelevel = samelevel.filter(function(c) {
            return compareArray(c.wins, a.wins) == 0;
        })
        addWins(samelevel);
    } while (samelevel.length < len);
    return - compareArray(a.wins, b.wins);       
});