Quiero ordenar una matriz bidimensional de enteros. ¿Cuál es la forma más simple y legible de lograr esto?
aporte:
[ [3,4,2], [5,1,3], [2,6,1], ]
producción:
[ [1,1,2], [2,3,3], [4,5,6] ]
Si necesita que las matrices más profundas también estén en orden, lo abordaría así:
Aplane las matrices usando flat()
, así que obtenga solo una lista regular
input.flat()
Ordenarlos usando una función de clasificación de enteros personalizada
.sort((a, b) => a - b)
Vuelva a crear la segunda dimensión
array_chunks(sortedArray, 3);
(Función utilizada tomada de esta respuesta )
const input = [ [3,4,2], [5,1,3], [2,6,1], ]; const array_chunks = (array, chunk_size) => Array(Math.ceil(array.length / chunk_size)).fill().map((_, index) => index * chunk_size).map(begin => array.slice(begin, begin + chunk_size)); let result = array_chunks(input.flat().sort((a, b) => a - b), 3); console.log(result);
[ [ 1, 1, 2 ], [ 2, 3, 3 ], [ 4, 5, 6 ] ]
Cuando se trabaja con arreglos anidados, es común trabajar desde el nivel más interno y luego salir. Usando este método, comenzamos con las matrices internas:
// Sorting the inner most array var result = []; [ [3,4,2], [5,1,3], [2,6,1], ].forEach(function(row) { // a for loop could work as well, this is just shorter. result.push(row.sort(function(a, b) { return ab; // ascending // return ba; // descending })); });
Luego, ordena la matriz externa. No puede ordenar la matriz externa como un solo número, por lo que es necesario decidir un método. Los ejemplos son: promedio de la matriz, valor más bajo o valor más alto.
// Using the first value to sort the outer array. [ [2,3,4], [1,3,5], [1,2,6], ].sort(function(a, b) { return a[0]-b[0]; });
Alternativamente
La salida deseada "[[1,1,2],[2,3,3],[4,5,6]]" ignora las matrices internas, por lo que no parece práctico. Sin embargo, para hacer esto, reconstruiríamos todas las matrices internas en una sola, ordenaríamos y luego reconstruiríamos una matriz anidada, suponiendo que cada nueva matriz tenga 3 valores.
var oneDimensionalArray = []; var finalArray = []; [ [3,4,2], [5,1,3], [2,6,1], ].forEach(function(row) { oneDimensionalArray = oneDimensionalArray.concat(row); }); oneDimensionalArray.sort(); for (var i=0; i<oneDimensionalArray.length; i++) { if (i%3==0) { temp = []; } temp.push(oneDimensionalArray[i]); if (i%3==2) { // 3 per line (0-2) finalArray.push(temp); } }
Nuevamente, no veo que esto tenga una utilidad práctica. Sería más fácil dejarlos como una matriz regular o comenzar con una configuración diferente si todos los datos se utilizarán de una manera que ignore la agrupación/matriz.
Este es un enfoque general de matriz anidada, que podría tener más matrices anidadas o diferentes longitudes.
Funciona tomando una matriz de índices para cada valor, una matriz plana de valores y, finalmente, asignando todos los valores a su lugar.
const getIndices = (value, index) => Array.isArray(value) ? value.flatMap(getIndices).map(array => [index, ...array]) : [[index]], setValue = (array, keys, value) => { const last = keys.pop(); keys.reduce((a, i) => a[i] ??= [], array)[last] = value; return array; }; data = [[3, 4, 2], [5, 1, 3], [2, 6, 1]], references = data.flatMap(getIndices), result = data .flat() .sort((a, b) => a - b) .reduce((r, v, i) => setValue(r, references[i], v), []); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }