Ordenamiento de un array de objetos por propiedad de cadena: analizamos una pregunta popular de Stack Overflow
\n\nImagina: tienes una lista de usuarios, productos o artículos. Cada elemento es un objeto con un montón de propiedades: nombre, precio, fecha, calificación. Y necesitas ordenar todo esto, digamos, por apellido en orden alfabético. Una tarea que parece simple, pero en la práctica presenta sorpresas. No es de extrañar que la pregunta "Sort array of objects by string property value" en Stack Overflow haya acumulado miles de visitas y decenas de respuestas.
\n\nEn este artículo no solo daremos código listo para usar. Analizaremos 5 formas de ordenamiento, desde lo básico hasta lo avanzado, identificaremos los errores típicos y mostraremos cómo evitarlos. Al final, podrás ordenar cualquier dato con una mano.
\n\n¿Qué es el ordenamiento de un array de objetos en JavaScript?
\n\nJavaScript tiene un método incorporado Array.prototype.sort(). Pero con objetos funciona de forma no intuitiva. Si llamas a sort() sin argumentos, intentará comparar los elementos como cadenas. Para números, esto da una sorpresa: [1, 20, 3].sort() devolverá [1, 20, 3], no [1, 3, 20]. Para objetos, es un caos total.
Por eso necesitamos una función de comparación (comparator). Esta recibe dos elementos y devuelve:
\n- \n
- un número negativo, si el primer elemento es menor que el segundo; \n
- 0, si son iguales; \n
- un número positivo, si el primero es mayor. \n
Aquí está la estructura básica del ordenamiento de un array de objetos por una propiedad de cadena:
\n\n// Array original\nconst users = [\n { name: 'Иван', age: 25 },\n { name: 'Анна', age: 30 },\n { name: 'Борис', age: 22 }\n];\n\n// Ordenamiento por el campo name\nusers.sort((a, b) => {\n if (a.name < b.name) return -1;\n if (a.name > b.name) return 1;\n return 0;\n});\n\nconsole.log(users);\n// [{ name: 'Анна', age: 30 }, { name: 'Борис', age: 22 }, { name: 'Иван', age: 25 }]\n\nEste código funciona, pero es voluminoso. Veamos cómo hacerlo más elegante.
\n\n5 formas de ordenar un array de objetos por cadena
\n\nForma 1: Función de comparación clásica
\n\nEl método más transparente. Es adecuado para cualquier cadena, incluido el cirílico, siempre que uses el orden alfabético correcto. La comparación con < y > tiene en cuenta los códigos de caracteres en Unicode, lo que para el idioma ruso da un resultado inesperado: «ё» terminará al final del alfabeto, y «я» estará cerca de «а».
const products = [\n { title: 'Яблоко', price: 50 },\n { title: 'Ёлка', price: 200 },\n { title: 'Ананас', price: 150 }\n];\n\n// Problema: 'Ёлка' se colocará después de 'Яблоко'\nproducts.sort((a, b) => {\n if (a.title < b.title) return -1;\n if (a.title > b.title) return 1;\n return 0;\n});\n\nCuándo usarlo: para cadenas en inglés, donde el orden alfabético coincide con Unicode.
\n\nForma 2: localeCompare — el salvador del cirílico
\n\nEl método String.prototype.localeCompare() tiene en cuenta las reglas de ordenamiento para un idioma específico. Para el ruso, pasamos 'ru'.
users.sort((a, b) => a.name.localeCompare(b.name, 'ru'));\n\nconsole.log(users);\n// [{ name: 'Анна', age: 30 }, { name: 'Борис', age: 22 }, { name: 'Иван', age: 25 }]\n\nEste código es más limpio, más corto y maneja correctamente «ё», «й» y otras letras. Si necesitas ordenar en orden descendente, simplemente intercambia a y b:
users.sort((a, b) => b.name.localeCompare(a.name, 'ru'));\n\nCuándo usarlo: siempre que trabajes con cirílico o datos multilingües.
\n\nForma 3: Ordenamiento que distingue entre mayúsculas y minúsculas
\n\nPor defecto, localeCompare distingue entre mayúsculas y minúsculas: «apple» se colocará antes que «Banana», porque la letra minúscula tiene