代码之家  ›  专栏  ›  技术社区  ›  Andrew

在Chrome中排序对象数组

  •  21
  • Andrew  · 技术社区  · 16 年前

    ECMA spec ,当两个对象在自定义排序中被确定为相等时,JavaScript是 使这两个物体保持相同的顺序。Chrome和Opera是唯一选择非稳定排序的两大浏览器,但其他浏览器包括Netscape 8&9、Kazehakaze、IceApe和其他一些。Chromium团队已经将这个bug标记为“按预期工作”,所以它不会被“修复”。如果需要数组在值相等时保持其原始顺序,则需要使用一些附加机制(如上面的机制)。返回 0


    我刚接到报告说我写的一些代码在Chrome上坏了。我已经找到了一个自定义方法来对一个对象数组进行排序。我真的很想称之为一个错误,但我不确定它是。

    在所有其他浏览器中,对对象数组排序时,如果两个对象解析为相同的值,则它们在更新数组中的顺序保持不变。在Chrome中,它们的顺序似乎是随机的。在Chrome和任何其他浏览器中运行下面的代码。你应该明白我的意思。

    我有两个问题:

    0 两个人比较了一下 保持原来的秩序(我觉得我错了)。

    sort 正在将解析与相同的值进行比较。换句话说,从不返回0。

    下面是示例代码:

    var x = [
    {'a':2,'b':1},
    {'a':1,'b':2},
    {'a':1,'b':3},
    {'a':1,'b':4},
    {'a':1,'b':5},
    {'a':1,'b':6},
    {'a':0,'b':7},
    ]
    
    var customSort = function(a,b) {
        if (a.a === b.a) return 0;
        if (a.a > b.a) return 1;
        return -1;
    };
    
    console.log("before sorting");
    for (var i = 0; i < x.length; i++) {
        console.log(x[i].b);
    }
    x.sort(customSort);
    
    console.log("after sorting");
    for (var i = 0; i < x.length; i++) {
        console.log(x[i].b);
    }
    

    在所有其他浏览器中,我看到的是只有数组的第一个成员和最后一个成员被移动(我看到 7,2,3,4,5,6,1 )但在Chrome中,内部数字似乎是随机的。

    [编辑]非常感谢所有回答的人。我想“不一致”并不意味着它是一个bug。另外,我只想指出 b 财产只是一个例子。事实上,我正在根据用户输入,在大约20个键中的任意一个上对一些相对较宽的对象进行排序。即使跟踪用户上一次排序的结果,也不能解决我看到的随机性问题。我的解决方案可能是这个的一个近似变体(突出显示了新代码):

    var x = [
    {'a':2,'b':1},
    {'a':1,'b':2},
    {'a':1,'b':3},
    {'a':1,'b':4},
    {'a':1,'b':5},
    {'a':1,'b':6},
    {'a':0,'b':7},
    ];
    var i;
    
    var customSort = function(a,b) {
        if (a.a === b.a) return a.customSortKey > b.customSortKey ? 1 : -1; /*NEW CODE*/
        if (a.a > b.a) return 1;
        return -1;
    };
    
    console.log("before sorting");
    for (i = 0; i < x.length; i++) {console.log(x[i].b);}
    
    for (i = 0; i < x.length; i++) {                      /*NEW CODE*/
        x[i].customSortKey = i;                           /*NEW CODE*/
    }                                                     /*NEW CODE*/
    x.sort(customSort);
    
    console.log("after sorting");
    for (i = 0; i < x.length; i++) {console.log(x[i].b);}
    
    3 回复  |  直到 11 年前
        1
  •  8
  •   lawnsea    7 年前

    不幸的是,V8排序并不稳定。我看看能不能找出这个问题的症结所在。

    V8排序是 now stable

        2
  •  22
  •   kennytm    16 年前

    ECMAScript标准 does not guarantee Array.sort is a stable sort in-place QuickSort internally (对于大小为22的数组,否则为插入排序)这是一种快速但 not stable .

    customSort .b 同时,消除了排序算法稳定性的需要。

        3
  •  8
  •   Mic    16 年前

    可能您已经知道了,但可以使用数组对多个列进行排序,以避免此错误:

    var customSort = function(a,b) {
        return [a.a, a.b] > [b.a, b.b] ? 1:-1;
    }