给出一系列像这样的对象:
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),以便获胜者是赢得每个指数中最多比较的人?
例如,对于爱丽丝,鲍勃和卡罗尔,爱丽丝应该获胜,因为她在可能的5中有3胜(3 <4 <5,2 <6 <7,5 <6 <8)。
更复杂的例子是
competitors = [{
name: "Dave",
scores: [8,1,1,8,4]
}, {
name: "Eve",
scores: [1,5,4,5,2]
}, {
name: "Frank",
scores: [6,2,3,4,7]
}];
此处,弗兰克输掉(1胜:4 <5 <8),而戴夫(2胜:1 <2 <5,1 <3 <4)和夏娃(2胜:1 <6 <8,2 <2) 4&lt; 7)领带。所以只用戴夫和夏娃重复这个过程,你可以打破平局。伊芙以3胜2负的成绩赢得决胜局。最后的排名是夏娃,戴夫,弗兰克。
我会提前知道每个参赛者的得分数(让我们称之为 numJudges ),以及可能得分的范围(让我们称之为1- numCompetitors < / em>的)。我也不关心浏览器支持,除了webkit的javascript引擎,所以这意味着支持ECMAScript 5和一些6(es5-compat-table),比如数组函数每个,地图,过滤,缩小。
答案 0 :(得分:1)
我发现它经常有助于将这样的大任务分成几个阶段。我怀疑它是否有效,但它可能对你有用。
开始:获取一个包含每个竞争对手结果的数组:
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 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]
答案 1 :(得分:0)
注意:我更喜欢@Tibos答案,但这个更简单。
您可以使用排序功能(Array.sort
):
function getWins(competitors, competitor) {
var scores = competitor.scores;
var wins = 0;
for (var i = 0, n = scores.length; i < n; i++) {
var win = true;
for (var j = 0, m = competitors.length; j < m; j++) {
// Do not compare the competitor with himself
if (competitors[j] !== competitor) {
// Do not count a win if someone beat him
if (competitors[j].scores[i] > scores[i]) {
win = false;
break;
}
}
}
if (win) {
wins++;
}
}
return wins;
}
// Sort competitors according to their wins
competitors.sort(function(a, b) {
return getWins(competitors, b) - getWins(competitors, a);
});
答案 2 :(得分:0)
一个特殊的比较函数可以计算下一关系的胜利,可以这样做:
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);
});