这是我的jsFiddle:
//Change this variable to change the number of players sorted
var numberOfPlayers = 15;
var teams = [];
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(var a=0; a<numberOfPlayers; a++){
updateStandings();
teams.push(new Team(alphabet.charAt(a)));
}
console.log("Teams:");
for(var x=0; x<teams.length; x++){
console.log(teams[x].name);
}
//Functions and such
function updateStandings(){
teams.sort(function(a, b) {
if(a.score == b.score){
if(a.tiebreak == b.tiebreak){
return teams.indexOf(a)-teams.indexOf(b);
}else{
return b.tiebreak-a.tiebreak;
}
}else{
return b.score-a.score;
}
});
}
function Team(name){
this.name = name;
this.score = 0;
this.tiebreak = 0;
}
我认为问题是javascript排序不稳定,并且改变了我的比较功能,但它仍然不起作用。
答案 0 :(得分:2)
JS中稳定排序的一般方法如下:
function stable_sort(array, sortfunc) {
function _sortfunc(a, b) { return sortfunc(array[a], array[b]) || a - b; }
return array.map((e, i) => i) . sort(_sortfunc) . map(i => array[i]);
}
这实际上做的是对索引列表进行排序。然后它将排序的索引列表映射回原始数组。重写sort函数以比较那些索引处数组中的值,如果它们相等则返回到索引本身的比较。
这种方法避免了代码中的问题,即它正在对正在排序的中间的数组进行indexOf
查找。
This question可以提供信息。
答案 1 :(得分:1)
根据文档,sort方法不需要稳定:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort在某些浏览器中它是稳定的,有些则不稳定。
您需要更改比较功能,但不能以您尝试的方式更改。原因是你比较
return teams.indexOf(a)-teams.indexOf(b);
当前数组中的。这意味着如果a和b的顺序在前面的步骤中发生了变化,那么排序例程将保留这个新顺序,而不是这些元素在开头的顺序。
有不同的解决方法。例如,您可以在排序之前创建数组的副本,并在此副本上执行indexOf。它将保留元素在排序开始之前的顺序。
但如果您事先知道订单,您也可以使用这些知识。例如,如果在排序之前团队按名称排序,您可以将名称比较为字符串而不是数组中的位置,它将比第一个选项更有效。
答案 2 :(得分:0)
因为JS&#39;排序通常是不稳定的。来自§22.1.3.24 of the spec:
此数组的元素已排序。排序不一定稳定(即,比较相等的元素不一定保持原始顺序)。
您的团队除了名称外都创建了相同的属性,因此实际执行排序的行是:
return teams.indexOf(a)-teams.indexOf(b);
因为您正在调用indexOf
,所以它会在每次重复排序时搜索项目(及其索引)。排序会改变数组(from MDN:它&#34;对数组的元素进行排序并返回数组&#34;)。
您正在搜索正在排序的同一数组中的项目,因此索引可能会在每次迭代时更改。正确地完成(相对而言),你可以用它做出永无止境的排序。
例如:
const data = [1, 3, 2, 4];
let reps = 0;
data.sort((a, b) => {
console.log(data);
const ia = data.indexOf(a), ib = data.indexOf(b);
if (ia === ib || reps > 50) {
return 0;
} else if (ia < ib) {
return 1;
} else if (ib < ia) {
return -1;
}
});
&#13;