Necesito ordenar una matriz de cadenas, donde los elementos se comparan lexicográficamente como secuencias de valores de puntos de código, de modo que, por ejemplo, "Z" < "a" < "\udabc" < "�" < "💩" .
"�" < "💩" aún debería mantenerse)? ¿Existe un procedimiento más eficiente para este caso especial? Nota: hay muchas respuestas en StackOverflow que explican cómo ordenar cadenas, pero usan el orden localeCompare o el orden definido por los operadores de comparación de JavaScript (que comparan cadenas como secuencias de unidades de código UTF-16). No estoy interesado en ninguno de los dos.
¿Cómo ordenar cadenas en JavaScript por valores de punto de código?
Parece ser un problema sorprendentemente difícil. Aquí hay una implementación de prueba de concepto (POC):
'use strict'; function compareCodePoints(s1, s2) { const len = Math.min(s1.length, s2.length); let i = 0; for (const c1 of s1) { if (i >= len) { break; } const cp1 = s1.codePointAt(i); const cp2 = s2.codePointAt(i); const order = cp1 - cp2; if (order !== 0) { return order; } i++; if (cp1 > 0xFFFF) { i++; } } return s1.length - s2.length; } let s =[]; let s1 = "abc𞸁z"; let s2 = "abc𞸂z"; s = [s1, s2]; console.log(s); s.sort(compareCodePoints); console.log(s); console.log() s = [s2, s1]; console.log(s); s.sort(compareCodePoints); console.log(s); console.log() s1 = "a"; s2 = ""; console.log([s1, s2]); console.log(compareCodePoints(s1, s2)); console.log([s2, s1]); console.log(compareCodePoints(s2, s1)); $ node codepoint.poc.js [ 'abc𞸁z', 'abc𞸂z' ] [ 'abc𞸁z', 'abc𞸂z' ] [ 'abc𞸂z', 'abc𞸁z' ] [ 'abc𞸁z', 'abc𞸂z' ] [ 'a', '' ] 1 [ '', 'a' ] -1 $