Estoy buscando ordenar una matriz de objetos JSON por orden ascendente de valores relacionados con otro valor. Suena confuso porque lo es. Tengo propiedades 'columna' y 'orden' en cada objeto en una matriz. Necesito que el orden sea como: el número más bajo en la columna 1, el número más bajo en la columna 2, el número más bajo en la columna 3, el segundo número más bajo en la columna 1, el segundo número más bajo en la columna 2, el segundo número más bajo en la columna 3 y continuar. Esto es fácil cuando 'order' tiene exactamente los mismos valores, puede usar una función de clasificación como:
function sortCourses(a, b){ if (a.order == b.order) { return (a.column - b.column); } else { return (a.order - b.order); } }El problema es que no siempre los tengo configurados así. Aquí hay una matriz de ejemplo:
[ { column: 2, order: 5 }, { column: 1, order: 1 }, { column: 3, order: 2 }, { column: 3, order: 1 }, { column: 1, order: 4 }, { column: 2, order: 1 }, { column: 3, order: 3 }, { column: 1, order: 3 }, { column: 2, order: 3 }, { column: 1, order: 2 } ]Después de ordenar, necesito que esta matriz se vea así:
[ { column: 1, order: 1 }, { column: 2, order: 1 }, { column: 3, order: 1 }, { column: 1, order: 2 }, { column: 2, order: 3 }, { column: 3, order: 2 }, { column: 1, order: 3 }, { column: 2, order: 5 }, { column: 3, order: 3 }, { column: 1, order: 4 } ]¿Alguna idea sobre cómo podría lograr esto?
Podría ser un poco más rápido, pero espero que sea fácil de seguir.
const data = [ { column: 2, order: 5 }, { column: 1, order: 1 }, { column: 3, order: 2 }, { column: 3, order: 1 }, { column: 1, order: 4 }, { column: 2, order: 1 }, { column: 3, order: 3 }, { column: 1, order: 3 }, { column: 2, order: 3 }, { column: 1, order: 2 } ]; // Sort by order. data.sort(function (a, b) { return (a.order - b.order); }); // Group by column. const groups = data.reduce( function (acc, value) { if (!acc[value.column]) { acc[value.column] = []; } acc[value.column].push(value); return acc; }, {}); // Get sorted columns. const cols = Object.keys(groups).map(Number).sort(); // Loop over columns taking lowest value until we're out of values. const out = []; while (out.length < data.length) { cols.forEach( function (col) { if (groups[col].length) { out.push(groups[col].shift(0)); } }); } console.log(out);Un camino bastante largo, pero todo lo que hago es simplemente agrupar cada 'grupo' (columnas) en un objeto, empujando sus órdenes en una matriz. Luego los clasifico y los pego.
var array = [ { column: 2, order: 5 }, { column: 1, order: 1 }, { column: 3, order: 2 }, { column: 3, order: 1 }, { column: 1, order: 4 }, { column: 2, order: 1 }, { column: 3, order: 3 }, { column: 1, order: 3 }, { column: 2, order: 3 }, { column: 1, order: 2 } ]; var new_array = {} for (let item of array) { if (item.column in new_array) { new_array[item.column].push(item.order); } else { new_array[item.column] = [item.order]; } } let max = 0; for (let key in new_array) { max = (max < new_array[key].length) ? new_array[key].length : max; new_array[key].sort(); } var final = []; for (let i = 0; i < max; i++) { for (let key in new_array) { if (i < new_array[key].length) { final.push({column: key, order: new_array[key][i]}); } } } console.log(final);