Tengo algunos problemas al tratar de ordenar/ordenar esta matriz de cadenas. Hay miles de nombres de archivos que aparecen en la respuesta, a continuación se muestra un ejemplo de 10.
array = [ 'ORDERHEADER_010122.arc', 'ORDERITEM_010122.arc', 'ORDERDETAIL_010122.arc', 'ORDERDETAIL_010222.arc', 'ORDERDETAIL_010322.arc', 'ORDERHEADER_010222.arc', 'ORDERHEADER_010322.arc', 'ORDERHEADER_010422.arc', 'ORDERITEM_010222.arc', 'ORDERDETAIL_010422.arc' ]; Un simple array.sort() se ocupa de la mitad del problema, ya que ordenará alfabéticamente las cadenas e inherentemente ordenará las fechas.
Lo que necesito es una especie de orden de "secuencia" junto con el orden de la fecha. Entonces prioSequence = ['ORDERHEADER', 'ORDERDETAIL', 'ORDERITEM']; sería la secuencia que quiero ver.
Salida esperada como:
array = [ 'ORDERHEADER_010122.arc', 'ORDERDETAIL_010122.arc', 'ORDERITEM_010122.arc', 'ORDERHEADER_010222.arc', 'ORDERDETAIL_010222.arc', 'ORDERITEM_010222.arc', 'ORDERHEADER_010322.arc', 'ORDERDETAIL_010322.arc', 'ORDERHEADER_010422.arc', 'ORDERDETAIL_010422.arc' ];¡Cualquier ayuda/orientación sería muy apreciada! ¡Gracias!
Prefije la cadena con las partes que determinan el orden, es decir, aammdd y 2 letras de la cadena "ORDER", ya que resulta que cuando elige la séptima y octava letra de esas palabras (EA, ET, TE), serán ordenado correctamente. Luego, después de haber ordenado los elementos, elimine ese prefijo nuevamente.
Así es como funciona:
let array = [ 'ORDERHEADER_010122.arc', 'ORDERITEM_010122.arc', 'ORDERDETAIL_010122.arc', 'ORDERDETAIL_010222.arc', 'ORDERDETAIL_010322.arc', 'ORDERHEADER_010222.arc', 'ORDERHEADER_010322.arc', 'ORDERHEADER_010422.arc', 'ORDERITEM_010222.arc', 'ORDERDETAIL_010422.arc' ]; let sorted = array.map(item => item.replace(/ORDER.(..).*?_(..)(..)(..).*/g, "$4$3$2$1") + item ).sort().map(s => s.slice(8)); console.log(sorted); Si tiene más palabras de prefijo de las que desea controlar el orden, cree una matriz de ellas en el orden esperado. La solución luego convertirá esa matriz en un mapa de búsqueda (dando un número de secuencia de 4 caracteres para una palabra dada). La llamada para replace necesita un argumento de devolución de llamada, que hará la búsqueda y los prefijos de esa secuencia. Aquí está el código para eso:
let array = [ 'ORDERHEADER_010122.arc', 'ORDERITEM_010122.arc', 'ORDERDETAIL_010122.arc', 'ORDERDETAIL_010222.arc', 'ORDERDETAIL_010322.arc', 'ORDERHEADER_010222.arc', 'ORDERHEADER_010322.arc', 'ORDERHEADER_010422.arc', 'ORDERITEM_010222.arc', 'ORDERDETAIL_010422.arc' ]; let priorities = [ 'ORDERHEADER', 'ORDERDETAIL', 'ORDERITEM', ]; // Map the priority array to an object for faster look-up let priMap = Object.fromEntries(priorities.map((word, i) => [word, ("000" + i).slice(-4)] )); let sorted = array.map(item => item.replace(/(.*?)_(..)(..)(..).*/g, (all, word, dd, mm, yy) => yy + mm + dd + (priMap[word] ?? "----") + all ) ).sort().map(s => s.slice(10)); console.log(sorted);Debe definir una función de comparación personalizada para su llamada de método de clasificación. Y, ese método primero debe comparar fechas y luego (si una fecha es la misma) ordenar prefijos de acuerdo con sus requisitos
Aquí está mi ejemplo
const order = new Map() // one can use plain Array + Array#indexOf later on .set('ORDERHEADER', 0) .set('ORDERDETAIL', 1) .set('ORDERITEM', 2) const compareFn = (a, b) => { const [a1, a2] = a.split('_') const [b1, b2] = b.split('_') const r2 = a2.localeCompare(b2) // TODO: re-write to date comparison a2 vs b2 if (r2 !== 0) return r2 return order.get(a1) - order.get(b1) // or Array#indexOf as mentioned above } // usage array.sort(compareFn)