He leído en la documentación sobre el trabajo de la función de comparación. Esta función de devolución de llamada puede tener 2 parámetros. Hay 3 "si" para ellos:
- Si
compareFunction(a, b)devuelve un valor > que 0, ordene b antes que a.- Si
compareFunction(a, b)devuelve un valor < que 0, ordene a antes de b.- Si
compareFunction(a, b)devuelve 0, a y b se consideran iguales.
Entonces, por lo que veo, si la función de comparación devuelve un valor menor que cero, el algoritmo de comparación no hace nada ( a y b permanecen en los mismos lugares) . Y si esta función devuelve un valor mayor que cero, a y b cambian ( b va primero) .
Está bien, eso es comprensible. Pero, ¿por qué mi código a continuación funciona así?
let arr1 = [9, 3, 6, 7, 1]; console.log(arr1.sort((a, b) => 1)); //1 > 0 -> compare function should switch elements let arr2 = [9, 3, 6, 7, 1]; console.log(arr2.sort((a, b) => -1)); //-1 < 0 -> compare function shouldn't switch elementsSu interpretación de los documentos es incorrecta.
Tu dices
-1significa que los elementos deben permanecer en el mismo lugar.
Eso está mal, los documentos simplemente indican que -1 significa que a debe ordenarse antes que b .
Dependiendo del algoritmo de clasificación subyacente, no hay garantía alguna de que, al llamar a la función de comparación con los parámetros a y b a esté actualmente antes que b en la matriz. Es decir, imagine una matriz [1,2,3] . Es posible que la función de comparación se llame con los parámetros (3, 1) o (1,3) . Pero si devuelve -1 en el primer caso, 1 y 3 cambiarán de posición. Y viceversa, si devuelve 1 en el segundo caso, 1 y 3 volverán a cambiar de lugar.
EDITAR
Diferentes navegadores implementan sort manera diferente. Por ejemplo, si ejecuta el siguiente fragmento en Chrome y en Firefox, obtendrá resultados diferentes.
var arr = [1,2,3,4,5,6,7,8,9]; arr.sort((a,b) => { console.log(`${a} ${b}`); return 1; }) console.log(arr); Por ejemplo, en mi cromo actual (versión 94.0.4606.61 en Windows), b será menor que a para todas las llamadas de la función de comparación y, por lo tanto, devolver 1 de la función de comparación significaría ordenar b antes que a que ya es el caso. . Así nada cambiará.
Mientras que en mi firefox (Versión 92.0 en Windows) b será mayor que a para todas las llamadas de la función de comparación. Y, por lo tanto, devolver 1 de la función de comparación significaría nuevamente ordenar b antes que a , lo cual no es el caso actualmente. Por lo tanto, la matriz se invertirá ...
Otros tiempos de ejecución con una implementación diferente de sort pueden conducir nuevamente a otros resultados totalmente impredecibles ...
Si la función de comparación devuelve una respuesta incorrecta cuando se le pregunta qué valor es menor que el otro, ¿por qué no esperaría una respuesta incorrecta de la función que depende de ella?
El algoritmo de ordenación probablemente hace el equivalente a dos pasadas antes de terminar y termina devolviendo los valores a su lugar en la segunda pasada.
Digo equivalente: podría estar pasando una vez, pero en los elementos de índice inferior lo ordena de una manera, y en los elementos superiores va de otra manera.
Para el segundo caso, considera los elementos superiores ordenados y luego los elementos inferiores que cree que tiene que cambiar.
Pero ordena todo el trabajo de manera diferente. Una ordenación por combinación puede depender de cuántas veces es divisible por 2. Una ordenación rápida puede depender de la posición del pivote. Una ordenación por inserción puede depender de que el número de elementos sea par o impar.
Así que dejando de lado la filosofía, la cuestión fundamental es la siguiente:
compare(1, 2) = 1, so switch. compare(2, 1) = 1, so switch.Si quería una razón por la cual su mala función de comparación hizo que la ordenación se comportara de la manera en que lo hizo, esa es la razón.
Si realmente desea que invierta el orden, entonces desea algo como:
function compare(int a, int b) { if (a < b) return 1; if (a > b) return -1; return 0; }