localeCompare

localeCompare compara dos strings usando reglas de idioma. Devuelve un número que se puede usar directamente dentro de sort o toSorted.

const result = "Ana".localeCompare("Zoe", "es");
 
// Negative number: "Ana" goes before "Zoe"

El valor devuelto sigue la misma regla que un comparator:

  • Menor que 0: el primer string va antes.
  • Igual a 0: ambos strings son equivalentes para esa comparación.
  • Mayor que 0: el segundo string va antes.

Problema que resuelve

Ordenar strings con sort() sin comparator compara por código Unicode, no por reglas naturales de idioma.

const names = ["Tatiana", "Oscar", "Óscar", "Zorro", "Nacho"];
 
const unicodeOrder = names.toSorted();
 
// ["Nacho", "Oscar", "Tatiana", "Zorro", "Óscar"]

Con localeCompare:

const names = ["Tatiana", "Oscar", "Óscar", "Zorro", "Nacho"];
 
const spanishOrder = names.toSorted((a, b) => a.localeCompare(b, "es"));
 
// ["Nacho", "Oscar", "Óscar", "Tatiana", "Zorro"]

Sintaxis

string.localeCompare(otherString, locales, options);
  • otherString: string contra el que se compara.
  • locales: idioma o lista de idiomas. Ejemplo: "es", "en", "fr".
  • options: configuración de sensibilidad, orden numérico, mayúsculas, etc.

Sensibilidad

La opción sensitivity controla qué diferencias importan.

const words = ["resume", "résumé", "Resume", "RESUME"];
 
const base = words.toSorted((a, b) =>
  a.localeCompare(b, "en", { sensitivity: "base" }),
);
 
// Uppercase letters and accents are considered equivalent

Valores habituales:

  • base: ignora acentos y mayúsculas.
  • accent: distingue acentos, ignora mayúsculas.
  • case: distingue mayúsculas, ignora acentos.
  • variant: distingue acentos, mayúsculas y variantes.

Búsqueda insensible a acentos y mayúsculas

Aunque localeCompare no reemplaza a un buscador, puede servir para igualdad flexible.

const isSameName = (a, b) => {
  return a.localeCompare(b, "es", { sensitivity: "base" }) === 0;
};
 
isSameName("Oscar", "Óscar"); // true
isSameName("ANA", "ana"); // true

Orden natural con números

Sin numeric: true, "item-10" puede ir antes que "item-2" porque compara texto.

const files = ["file-1", "file-10", "file-2", "file-20"];
 
const naturalOrder = files.toSorted((a, b) => {
  return a.localeCompare(b, "es", { numeric: true });
});
 
// ["file-1", "file-2", "file-10", "file-20"]

Este patrón se usa mucho para nombres de archivos, capítulos, versiones simples, tickets y códigos humanos.

Ordenar objetos por texto

Patrón típico en tablas y listados.

const products = [
  { name: "Álbum" },
  { name: "agenda" },
  { name: "Archivador" },
  { name: "ábaco" },
];
 
const sortedProducts = products.toSorted((a, b) => {
  return a.name.localeCompare(b.name, "es", {
    sensitivity: "base",
  });
});
 
// ábaco, agenda, Álbum, Archivador

Ordenar por texto y desempatar por número

Algoritmo muy usado para tablas: ordenar por nombre y, cuando hay empate, por otro criterio.

const rows = [
  { category: "Frontend", priority: 2, title: "CSS" },
  { category: "Backend", priority: 1, title: "SQL" },
  { category: "Frontend", priority: 1, title: "React" },
  { category: "Backend", priority: 3, title: "Node" },
];
 
const sortedRows = rows.toSorted((a, b) => {
  return (
    a.category.localeCompare(b.category, "es") ||
    a.priority - b.priority ||
    a.title.localeCompare(b.title, "es")
  );
});
 
// Backend priority 1, Backend priority 3, Frontend priority 1, Frontend priority 2

Intl.Collator

Si vas a ordenar muchos elementos con las mismas reglas, Intl.Collator es más cómodo y puede ser más eficiente que crear opciones en cada comparación.

const collator = new Intl.Collator("es", {
  numeric: true,
  sensitivity: "base",
});
 
const files = ["Archivo 2", "archivo 10", "Árchivo 1"];
 
const sortedFiles = files.toSorted(collator.compare);
 
// ["Árchivo 1", "Archivo 2", "archivo 10"]

Opciones útiles

const collator = new Intl.Collator("es", {
  numeric: true,
  sensitivity: "base",
  ignorePunctuation: true,
});
  • numeric: true: ordena números dentro de strings de forma natural.
  • sensitivity: "base": ignora acentos y mayúsculas.
  • ignorePunctuation: true: ignora puntuación al comparar.
  • caseFirst: "upper" o "lower": prioriza mayúsculas o minúsculas cuando la sensibilidad lo permite.

Regla práctica

Usa localeCompare para ordenar o comparar texto visible para personas. Usa comparadores numéricos para números puros y fechas convertidas a timestamp.