Ordenar matrices en JavaScript

Como muchos otros lenguajes, JavaScript ofrece métodos prácticos para clasificar matrices. Si bien el resultado es el mismo, los motores de JavaScript implementan diferentes algoritmos, que trataremos en este artículo.

Al igual que muchos otros lenguajes populares, JavaScript viene convenientemente con un método incorporado para ordenar matrices. Si bien el resultado final es el mismo, los diversos motores de JavaScript implementan este método utilizando diferentes algoritmos de ordenación:

  • V8: Clasificación rápida o clasificación por inserción (para arreglos más pequeños)
  • Firefox: ordenar por fusión
  • Safari: Quicksort, Merge Sort o Selection Sort (según el tipo de matriz)

La implementación realmente no importa para el código de llamada, pero es interesante ver estos algoritmos de clasificación utilizados en la práctica después de aprender sobre ellos durante tanto tiempo en las clases de introducción de CS.

Esta función de ordenación está disponible como método prototipo en la clase Array:

1
Array.sort([compareFunc])

Al estilo de JavaScript, se pasa una devolución de llamada a esta función que se usa para decirle al algoritmo de clasificación cómo se comparan dos elementos entre sí. compareFunc debe tener dos parámetros, a y b, y funciona así:

  • Si compareFunc devuelve 0, los elementos se tratan como iguales
  • Si compareFunc devuelve 1, entonces b se ordena antes que a
  • Si compareFunc devuelve -1, entonces a se ordena antes que b

La función no necesariamente tiene que devolver 1 o -1, siempre y cuando los números devueltos sean 0, por encima de 0 o por debajo de 0. Entonces, una función de comparación como (a, b) => a - b; es perfectamente valido.

Si no se proporciona compareFunc, los elementos se convierten en cadenas y luego se ordenan alfabéticamente. Esto hace que la clasificación de cadenas sea trivial. Sin embargo, aunque parece que ordenar números debería ser sencillo, en realidad puede ser un poco confuso aquí:

1
2
3
> let nums = [3, 2, 6, 50, 10];
> nums.sort()
[ 10, 2, 3, 50, 6 ]

Como puede ver, los números no están en el orden que esperaba. Esto se debe a que, como se mencionó anteriormente, el método de clasificación predeterminado es convertir los elementos en cadenas antes de realizar la comparación. Y como cadena, "50" viene antes de "6", por lo que 50 no es el último en la matriz. Para ordenar esta matriz correctamente, intente lo siguiente en su lugar:

1
2
3
> let nums = [3, 2, 6, 50, 10];
> nums.sort((a, b) => a - b);
[ 2, 3, 6, 10, 50 ]

Nota: es importante tener en cuenta que este método ordena in situ, lo que significa que la matriz original se ordena y no se realiza ninguna copia. Entonces, mientras que el método .sort() devuelve la matriz ordenada, en realidad no necesita asignarlo a nada, ya que la matriz a la que se llama está ordenada.

Si desea invertir el orden de clasificación, simplemente cambie la comparación de a y b. Entonces, si queremos que los números estén en orden descendente, haría lo siguiente:

1
2
3
> let nums = [3, 2, 6, 50, 10];
> nums.sort((a, b) => b - a);
[ 50, 10, 6, 3, 2 ]

Clasificación de matrices de objetos

El uso de una función de comparación como esta hace que sea extremadamente fácil ordenar objetos personalizados en JavaScript. Por ejemplo, digamos que tenemos la siguiente lista de datos de usuario:

1
2
3
4
5
6
7
let users = [
    {name: 'Scotty', age: '18'},
    {name: 'Tommy', age: '21'},
    {name: 'Sally', age: '71'},
    {name: 'Billy', age: '18'},
    {name: 'Timmy', age: '21'}
];

Esto no es algo que el algoritmo de clasificación pueda simplemente interpretar y clasificar por sí mismo. El orden también depende en gran medida de la aplicación. ¿Qué pasa si queremos ordenar por edad y luego nombre? Para hacerlo, podríamos proporcionar un comparador que combine los dos:

1
2
3
4
5
6
7
users.sort((a, b) => {
    let keyA = a.age + a.name;
    let keyB = b.age + b.name;
    if (keyA < keyB) return -1;
    if (keyA > keyB) return 1;
    return 0;
});

Esto dará como resultado la siguiente matriz ordenada:

1
2
3
4
5
[ { name: 'Billy', age: '18' },
  { name: 'Scotty', age: '18' },
  { name: 'Timmy', age: '21' },
  { name: 'Tommy', age: '21' },
  { name: 'Sally', age: '71' } ]

Observe que ahora todos los usuarios están ordenados por edad. Y como estaba previsto, los usuarios con la misma edad se ordenan por nombre, como Billy y Scotty.

Conclusión

En este breve artículo, vimos cómo usar el método integrado .sort() para clasificar fácilmente las matrices en JavaScript. Esto se aplica a cualquier tipo de datos, incluidas cadenas, números o incluso objetos. El orden de clasificación está determinado por el método de devolución de llamada compareFun, que es lo que le permite determinar el orden de clasificación o qué propiedades del objeto determinan el orden de clasificación.