sort por ordenar objetos objects numeros multidimensional fecha array javascript sorting google-chrome

javascript - por - Ordenando una matriz de objetos en Chrome



ordenar numeros javascript (3)

El estándar ECMAScript no garantiza que Array.sort sea ​​estable . Chrome (el motor V8) utiliza QuickSort localmente (para matrices de tamaño ≥ 22, de lo contrario, ordenación por inserción) que es rápido pero no estable .

Para solucionarlo, haga que customSort compare con customSort también, eliminando la necesidad de estabilidad del algoritmo de clasificación.

EDITAR: Tal como lo señala kennytm a continuación y después de investigarme a mí mismo, de acuerdo con las especificaciones de ECMA , cuando se determina que dos objetos son iguales en una clasificación personalizada, JavaScript no necesita 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 y 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 te molestes. O use una biblioteca que admita una clasificación estable, como Underscore / Lodash.

Acabo de recibir un informe de que un 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, ¿tenía razón al suponer que cuando el clasificador personalizado devuelve 0 los dos elementos comparados deben permanecer en su orden original (tengo la sensación de que estaba equivocado).

En segundo lugar, ¿hay alguna buena manera de arreglar 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 de sort comparan la resolución con el mismo valor. En otras palabras, nunca devuelva 0.

Aquí está el código de muestra:

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 otros navegadores, lo que veo es que solo el primer miembro y el último miembro de la matriz se mueven (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. Probablemente mi trabajo alternativo sea una variación cercana de esto (el nuevo código se resalta):

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


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


Puede ser que ya lo sepas, pero puedes usar una matriz para ordenar en varias columnas y evitar este error:

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