随后的多维数组排序会产生意外结果

时间:2013-09-02 20:14:47

标签: javascript arrays sorting multidimensional-array

我有一个排序异常,我可以在Chrome版本28.0.1500.71 Ubuntu 12.04(28.0.1500.71-0ubuntu1.12.04.1)中重现,这是我今天可以使用的所有内容,但我看到了相同的结果Firefox的最新版本。

给出以下代码:

<SCRIPT type="text/javascript">
var ary=[];
for(var x=0; x<11; x++){
    var tmp=[];
    tmp[0]="COL" + ("00" + x).substr(-3);
    tmp[1]= Math.floor(x/3);
    ary[x]=tmp;
}
ary.sort(function(a,b){
    if(a[0]>b[0]){return 1}
    if(a[0]<b[0]){return -1}
    return 0;
});
console.log(ary.toString());
ary.sort(function(a,b){
    if(a[1]>b[1]){return 1}
    if(a[1]<b[1]){return -1}
    return 0;
});
console.log(ary.toString());
</SCRIPT>

你可以(可能)看到,第一次排序的结果显示ary []按列0正确排序,但在第二次排序后,当[1] == b [1]时,排序以前执行过的(现在)可能会被逆转。

如果x的迭代次数较少,则第二次排序(可能)会返回预期结果。

我已经看了一段时间,但是现在我需要能够按一个任意列排序多达15000行,然后另一个,然后另一个,而不会丢失先前排序的排序顺序[ ?] == b [?]。我认为这是预期的行为。

我猜这是一个内置于javascript排序算法中的节省时间的功能,但是会产生无法预料的副作用。

当当前排序中的== b时,是否有一个神奇的子弹可以让我不必遍历每个先前的排序?

修改: @ameer:好的,这是一个可行的“魔术子弹”吗?

我们可以为数组添加一个索引值,当我们排序时,如果我们的值相等,我们就可以按索引本身排序。

for(var x=0; x<ary.length; x++){ary[x].index = x;}
ary.sort(function(a,b){
    if(a[2]>b[2]){return 1;}
    if(a[2]<b[2]){return -1;}
    if(a.index>b.index){
        return 1;
    }
    return -1;
});

当我们放入索引时,我们可以知道先前的排序对数组做了什么,并且在我们当前的排序中保持该排序顺序应为[?] == b [?]。

我想知道这有多快 - 我还想知道如何在排序期间重新编号索引,而不是在每次排序之前重新创建它们,但我担心它会抛弃相等值的排序。也许我们可以添加在排序期间更改的newIndex属性,然后将index的值设置为newIndex值。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

问题是javascript中的排序不能保证稳定(如果元素相等,则不保证元素的顺序保留)请参阅here