为什么我的Javascript程序中的Array.sort()方法不稳定
Why is the Array.sort() method in my Javascript program unstable?
这是我的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排序不稳定,并更改了比较函数,但它仍然不起作用。
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]);
}
这实际上是对索引列表进行排序。然后,它将已排序的索引列表映射回原始数组。排序函数被重写以比较数组中那些索引处的值,如果它们相等,则返回到索引本身的比较。
这种方法避免了代码中的问题,即它正在对处于排序中间的数组进行indexOf
查找。
这个问题可能会提供信息。
根据文档,排序方法不需要稳定:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort在某些浏览器中它是稳定的,而在某些浏览器则不然。
您确实需要更改比较函数,但不要像您尝试的那样。原因是你比较
return teams.indexOf(a)-teams.indexOf(b);
在电流阵列中。这意味着,如果a和b的顺序在前面的步骤中发生了变化,则排序例程将保留这个新顺序,而不是这些元素一开始的顺序。
有不同的方法来解决它。例如,您可以在排序之前创建数组的副本,并在此副本上执行indexOf。它将保留元素在开始排序之前的顺序。
但如果你事先知道订单,你也可以运用这些知识。例如,如果在排序之前,团队是按名称排序的,那么您可以将名称作为字符串而不是数组中的位置进行比较,这将比第一个选项高效得多。
因为JS的排序通常不稳定。规范§22.1.3.24:
此数组的元素已排序。排序不一定是稳定的(也就是说,比较相等的元素不一定保持其原始顺序)。
您的团队创建时除了名称外具有相同的属性,因此实际执行排序的行是:
return teams.indexOf(a)-teams.indexOf(b);
因为您调用的是indexOf
,所以它在每次重复排序时都会搜索项(及其索引)。排序会使数组发生变化(来自MDN:它"将数组的元素排序到适当的位置并返回数组")。
您正在排序的同一数组中搜索项,因此索引可能会在每次迭代中更改。如果做得正确(相对而言),你可以用它产生一种永无止境的东西。
例如:
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;
}
});
- electronic BrowserWindow的最小高度和宽度在hide()show()方法之后不起作用
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 数组在递归方法中设置为null
- 打破承诺链的好方法是什么
- 在使用Polymer'加载所有json文件后执行方法;s的核心ajax
- 使用“;这个“;JavaScript原型方法中的关键字
- 序列化数据属性中对象的最可靠方法
- 使用Objective-C的JavaScript注入方法
- 有没有一种方法可以添加相同的项目val=“0”;4〃;到JavaScript中数组的每个对象
- 有没有一种方法可以防止img get请求使用css或js发生
- Javascript,有没有一种方法可以将数组写成没有逗号或空格的单个文本字符串
- sort和reverse方法在JavaScript中无法正常工作
- 在 compare函数 .sort() 方法中传递其他参数
- 在Javascript的“sort”方法中调用函数
- 为什么这个例子要遍历数组进行排序,而不是使用.sort()方法
- array.sort()方法中反向比较函数背后的逻辑
- JavaScript[].Sort()方法在应该保留元素时进行排序
- Javascript,如何编写数组.Sort方法,以便通过超时策略调用它
- 为什么我的Javascript程序中的Array.sort()方法不稳定
- 这个函数是如何与javaScript中的sort方法交互的