Ordenar Arrays
Clase 5 de 84 min de lectura
Ordenar una lista de números de menor a mayor parece lo más fácil del mundo. Pues en JavaScript tiene trampa: los arrays traen un método .sort() que, tal cual viene, da resultados que no te esperas. La buena noticia es que puedes decirle exactamente cómo quieres que ordene.
Ordenamiento básico con sort()#
Empecemos por el susto. Llama a .sort() sin pasarle nada y mira el resultado:
let numeros = [5, 10, 2, 25, 7]numeros.sort()console.log(numeros) // -> [10, 2, 25, 5, 7]¿El 10 antes que el 2? ¿Qué ha pasado? Por defecto, .sort() ordena los elementos según su valor como cadena de texto, no según su valor numérico. Como en un diccionario, '10' va antes que '2' porque empieza por '1'.
Con números, este comportamiento resulta muy confuso. Por suerte, podemos arreglarlo.
Ordenamiento personalizado con sort()#
Para decidir cómo se ordena, a sort() le puedes pasar una función de comparación. Esa función recibe dos elementos del array, a y b, y con lo que devuelve le dice a sort() cuál va primero:
- Un valor negativo si
adebe aparecer antes queb. - Un valor positivo si
bdebe aparecer antes quea. - Cero si los dos son iguales.
Con números basta con restarlos: si a es menor que b, a - b sale negativo y a se queda delante. Así ordenas de menor a mayor:
let numeros = [5, 10, 2, 25, 7]numeros.sort(function(a, b) { return a - b})console.log(numeros) // -> [2, 5, 7, 10, 25]¿Y de mayor a menor? Le das la vuelta a la resta en el return:
let numeros = [5, 10, 2, 25, 7]numeros.sort(function(a, b) { return b - a})console.log(numeros) // -> [25, 10, 7, 5, 2]Así se ve la diferencia entre ordenar sin función y con una función de comparación:
[2, 5, 7, 10, 25]. Con b - a obtendrías el orden contrario, de mayor a menor.Como la función solo hace una resta, con una arrow function cabe en una línea:
let numeros = [5, 10, 2, 25, 7]numeros.sort((a, b) => a - b)sort() y toSorted()#
En ningún ejemplo hemos guardado el resultado en otra variable. No hace falta, porque .sort() modifica el array original.
¿Y si quieres un array ordenado sin tocar el que ya tenías? Usa .toSorted(): funciona igual, pero devuelve un array nuevo. Compara las dos últimas líneas:
let numeros = [5, 10, 2, 25, 7]let numerosOrdenados = numeros.toSorted((a, b) => { return a - b})console.log(numerosOrdenados) // -> [2, 5, 7, 10, 25]console.log(numeros) // -> [5, 10, 2, 25, 7]La alternativa que funciona en todas partes es crear primero una copia con el operador de propagación (...) y ordenar esa copia:
let numeros = [5, 10, 2, 25, 7]const copiaNumeros = [...numeros]// ordenamos la copia y no el originalcopiaNumeros.sort((a, b) => a - b)console.log(copiaNumeros) // -> [2, 5, 7, 10, 25]console.log(numeros) // -> [5, 10, 2, 25, 7]En resumen
.sort()sin argumentos ordena como si todo fuera texto: por eso el 10 queda antes que el 2.- Para ordenar números, pásale una función de comparación:
(a, b) => a - bde menor a mayor y(a, b) => b - ade mayor a menor. .sort()modifica el array original.- Si no quieres tocarlo, usa
.toSorted()o crea antes una copia con[...array].