El metodo sort() se usa para ordenar los valores de un array en JavaScript y este nos va a devolver el mismo array ya ordenado, aunque siendo sus resultados algo imprevisibles. Vamos a ver cómo trabajar con este método a través de unos ejemplos prácticos.
El método sort()
funciona de tal manera que convierte todos sus elementos a cadenas y compara su valores en las tablas Unicode. Por lo que cuando estamos ordenando un array numérico, case sensitive, con acentos u otro tipo de caracteres especiales sus resultados pueden desconcertarnos.
Veamos este tipo de comportamiento con un ejemplo: tenemos un array de elementos en mayúsculas y acentuados (el resultado que obtenemos es una ordenación a medias).
1 2 3 |
let provincias = ["León", "Salamanca", "Valladolid", "Ávila", "Burgos"]; provincias.sort(); console.log(provincias); // (5) ["Burgos", "León", "Salamanca", "Valladolid", "Ávila"] |
El resultado de la ordenación anterior no es correcta por lo que tendremos que recurrir a una función de ordenación. Opcionalmente sort() nos permite usar una función de ordenación y que nos va a permitir definir el orden de los elementos dentro de un array.
En este caso para ordenar las cadenas usaremos el método localeCompare()
que nos permite comparar una cadena con otra (retornando un número positivo, negativo o cero). Por lo que ya tenemos una ordenación más lógica en este tipo de casos.
1 2 3 4 |
provincias.sort( (a, b) => { return a.localeCompare(b, 'es-ES'); }) console.log(provincias); // (5) ["Ávila", "Burgos", "León", "Salamanca", "Valladolid"] |
Ordenación de arrays numéricos
sort()
convierte los elementos del array a cadenas por lo que con los números nos va a pasar lo mismo y tampoco no devolverá una ordenación lógica.
1 2 3 |
numeros = [ 100, 10, 1, 5, 50]; numeros.sort(); console.log(numeros); // (5) [1, 10, 100, 5, 50] |
1 2 3 |
numeros = [ 100, 10, 1, 5, 50]; numeros.sort( (a,b) => { return a-b; }); console.log(numeros); // (5) [1, 5, 10, 50, 100] |
Ordenación de array de objetos por valor de su propiedad
Los objetos de un array también pueden ser ordenados por el valor de sus propiedades. La función de ordenación si retorna 1 indica que la propiedad b tiene precedencia sobre la propiedad a y al contrario cuando retorna -1.
1 2 3 4 5 6 7 8 9 10 |
let productos = [ { ref: 'p1', color: 'blanco', talla: 'S' }, { ref: 'p2', color: 'blanco', talla: 'L' }, { ref: 'p3', color: 'verde', talla: 'M' }, { ref: 'p4', color: 'rojo', talla: 'L' }, { ref: 'p5', color: 'azul', talla: 'L' } ] // ordenación por colores productos.sort( (a, b) => (a.color > b.color) ? 1 : -1) console.log(productos) |
Ahora vamos a crear un ejemplo algo mas complejo donde tendremos que ordenar las opciones de un campo <select>
. Por lo que primero leemos las opciones del selector y a continuación creamos un array de objetos temporal con todos su valores y atributos. Finalmente ordenaremos este array de objetos por una de sus propiedades y rehacemos las opciones del selector usando el nuevo array que hemos creado.
1 2 3 4 5 6 7 |
<select name="provincias" class="provincias"> <option label="León" value="10">León</option> <option label="Salamanca" value="20">Salamanca</option> <option label="Valladolid" value="30">Valladolid</option> <option label="Ávila" value="40">Ávila</option> <option label="Burgos" value="50">Burgos</option> </select> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
tmp = []; provincias = document.querySelector('.provincias'); for ( let i=0; i<provincias.length;i++) { tmp.push( { id: provincias[i].value, label: provincias[i].label, text: provincias[i].text } ) } // ordenamos el array de objetos por el valor de su propiedad label tmp.sort( (a,b) => { return a.label.localeCompare(b.label); } ) // reorganizamos las opciones del elemento HTML5 <select> ya ordenadas for ( let i = 0; i<tmp.length;i++) { provincias[i] = new Option(tmp[i].text, tmp[i].id, false, false ); // Option(text, value, defaultSelected, Selected) provincias[i].setAttribute('label', tmp[i].label); } |
El resultado es un campo <select> con todos los valores de sus opciones ordenados alfabéticamente.