2010-07-07 24 views
21

EDITAR: Según lo observado por kennytm a continuación y después de investigarme, según el ECMA spec, cuando dos objetos se determinan para ser iguales en una clasificación personalizada, JavaScript es no requerido para dejar esos dos objetos en el mismo orden Tanto Chrome como Opera son los únicos dos buscadores principales que eligen tener géneros no estables, pero otros incluyen Netscape 8 & 9, Kazehakaze, IceApe y algunos otros. El equipo de Chromium ha marcado este error como "Funcionando según lo previsto", por lo que no será "reparado". Si necesita que sus matrices permanezcan en su orden original cuando los valores son iguales, necesitará emplear algún mecanismo adicional (como el anterior). Devolver 0 al ordenar objetos no tiene sentido, así que no se moleste. O use una biblioteca que admita una clasificación estable, como Underscore/Lodash.Ordenando una matriz de objetos en Chrome


Acabo de recibir un informe de que algún código que escribí está rompiendo Chrome. Lo he rastreado a un método personalizado que estoy usando para ordenar una matriz de objetos. Estoy realmente tentado de llamar a esto un error, pero no estoy seguro de que lo sea.

En todos los otros navegadores cuando ordena una matriz de objetos, si dos objetos se resuelven con el mismo valor, su orden en la matriz actualizada no se modifica. En Chrome, su orden es aparentemente aleatoria. Ejecute el siguiente código en Chrome y en cualquier otro navegador que desee. Deberías ver lo que quiero decir.

Tengo dos preguntas:

En primer lugar, fue en lo cierto al suponer que cuando el clasificador personalizada devuelve 0 que los dos puntos en comparación debe permanecer en su orden original (Tengo la sensación de que estaba equivocado).

En segundo lugar, ¿hay alguna forma de corregir esto? Lo único que se me ocurre es agregar un número de incremento automático como atributo a cada miembro de la matriz antes de ordenarlo, y luego usar ese valor cuando dos elementos sort comparan la resolución con el mismo valor. En otras palabras, nunca se devuelve 0.

Aquí está el código de ejemplo:

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); 
} 

En todos los demás navegadores, lo que veo es que sólo el primer elemento y el último miembro de la matriz son movidos (Veo 7,2,3,4,5,6,1) pero en Chrome los números internos son aparentemente aleatorios.

[EDITAR] Muchas gracias a todos los que respondieron. Supongo que 'inconsistente' no necesariamente significa que es un error. Además, solo quería señalar que mi propiedad b era solo un ejemplo. De hecho, estoy ordenando algunos objetos relativamente anchos en cualquiera de las cerca de 20 teclas según la entrada del usuario. Incluso mantener un registro de lo que el usuario ordenó por última vez no resolverá el problema de la aleatoriedad que estoy viendo. Mi trabajo en torno probablemente será una variación cierre de este (nuevo código está resaltado):

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);} 

Respuesta

7

El V8 tipo no es estable, por desgracia. Veré si puedo desenterrar el error de Chromium sobre esto.

+6

[V8 tema 90: V8 no ordena estable] (http: // código .google.com/p/v8/issues/detail? id = 90 "V8 bug 90") – lawnsea

8

Puede ser que usted lo sepa ya, pero se puede utilizar una matriz para clasificar en varias columnas y evitar este error:

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