Estoy tratando de ordenar una matriz:
["B3", "D2", "F1", "A9", "D12", "A2", "C1", "Z0", "B1"]
El resultado esperado debe ser:
["Z0", "B1", "C1", "F1", "A2", "D2", "B3", "A9", "D12"]
Aquí está mi código:
let array = ["B3", "D2", "F1", "A9", "D12", "A2", "C1", "Z0", "B1"]; let collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base", }); console.log(array.sort(collator.compare));
Luego, la salida se ordena primero por Alfabeto, lo que da:
["A2", "A9", "B1", "B3", "C1", "D2", "D12", "F1", "Z0"]
Así que descubrí que si cambio la posición de cada valor de esta manera:
["3B", "2D", "1F", "9A", "12D", "2A", "1C", "0Z", "1B"]
Y luego páselo de nuevo en el intercalador, me dará la secuencia ordenada correcta, pero solo que el número y las letras están invertidos. Entonces tendré que darles la vuelta. ¿Hay una mejor manera de hacer esto?
Si siempre tiene una sola letra, puede ordenar por el resto numérico y por la primera letra.
const array = ["B3", "D2", "F1", "A9", "D12", "A2", "C1", "Z0", "B1"]; array.sort((a, b) => a.slice(1) - b.slice(1) || a[0].localeCompare(b[0])); console.log(...array);
Si tiene más de una letra, puede tomar una expresión regular y obtener solo dígitos y no dígitos, separados en un objeto.
const getValues = string => ({ letters: string.match(/\D+/)[0], digits: string.match(/\d+/)[0] }), array = ["B3", "D2", "F1", "A9", "D12", "A2", "C1", "Z0", "B1"]; array.sort((a, b) => { const [aa, bb] = [a, b].map(getValues); return aa.digits - bb.digits || aa.letters.localeCompare(bb.letters); }); console.log(...array);