Tengo una tarea para ordenar una matriz de números aleatorios por un cierto orden que se da desde otra matriz. Todos los demás elementos que no se pudieron ordenar deben aterrizar al final de la matriz de resultados:
const array = [6,1,2,3,4,5] const sortOrder = [3,2,1] const shouldSortTo = [3,2,1,6,4,5]Tengo la siguiente solución:
array.sort((a,b)=> { if(sortOrder.indexOf(a) === -1 && sortOrder.indexOf(b) > -1 ) { return 1 } if(sortOrder.indexOf(a) > -1 && sortOrder.indexOf(b) === -1 ) { return -1 } return sortOrder.indexOf(a) - sortOrder.indexOf(b) })Funciona pero tengo la sensación de que no es fácil de leer o entender. ¿Hay una manera mejor o más corta de hacerlo?
No digo que esto sea mejor o más eficiente, pero primero puede verificar si todos los elementos de orden de clasificación están en la matriz, luego elimine los elementos de orden de clasificación de la matriz y concatene los dos:
const array = [6,1,2,3,4,5] const sortOrder = [3,2,1] const shouldSortTo = [3,2,1,6,4,5] let result = sortOrder.filter(s => array.includes(s)).concat(array.filter(i => !sortOrder.includes(i))) console.log(result)Editar: según el comentario de @epascarello, esta puede ser una mejor opción si la matriz contiene valores duplicados:
const array = [6,1,2,3,4,5,2,3] const sortOrder = [3,2,1] let sorted = sortOrder.reduce((s, i) => [...s, ...array.filter(x => x === i)], []) let result = sorted.concat(array.filter(i => !sortOrder.includes(i))) console.log(result)No seguiría buscando en el índice. Solo léelo una vez y úsalo. Puede aplicarlo a su propio código.
const array = [6,1,2,3,4,5] const sortOrder = [3,2,1] array.sort((a,b)=> { const aI = sortOrder.indexOf(a); const bI = sortOrder.indexOf(b); if (aI === -1 && bI > -1 ) return 1; else if (aI > -1 && bI === -1 ) return -1; return aI - bI; }) console.log(array);Verificaría si ambos son iguales y devolverían cero. Verificaría que cualquiera sea -1. Y finalmente ordenaría la base en el índice.
const array = [6,1,2,3,4,5] const sortOrder = [3,2,1] array.sort((a,b)=> { const aI = sortOrder.indexOf(a); const bI = sortOrder.indexOf(b); if (aI === bI) return 0; else if (aI === -1) return 1; else if (bI === -1) return -1; else return aI - bI; }) console.log(array);Otra opción, si -1, establece la longitud de la matriz y simplemente resta
const array = [6,1,2,3,4,5] const sortOrder = [3,2,1] const max = array.length; array.sort((a,b)=> { const aI = sortOrder.indexOf(a); const bI = sortOrder.indexOf(b); return (aI === -1 ? max : aI) - (bI === -1 ? max : bI); }) console.log(array);O puedes reservar la lógica
const array = [6,1,2,3,4,5] const sortOrder = [3,2,1] const max = array.length; const reversed = sortOrder.slice().reverse(); array.sort((a,b)=> { const aI = max - reversed.indexOf(a); const bI = max - reversed.indexOf(b); return aI - bI; }) console.log(array);