¿Alguien puede ayudarme a ordenar una matriz bidimensional en JavaScript?
Tendrá datos en el siguiente formato:
[12, AAA]
[58, BBB]
[28, CCC]
[18, DDD]
Debería verse así cuando se ordena:
[12, AAA]
[18, DDD]
[28, CCC]
[58, BBB]
Básicamente, ordenando por la primera columna.
Salud

Respuestas:
Es así de simple:
var a = [[12, 'AAA'], [58, 'BBB'], [28, 'CCC'],[18, 'DDD']]; a.sort(sortFunction); function sortFunction(a, b) { if (a[0] === b[0]) { return 0; } else { return (a[0] < b[0]) ? -1 : 1; } }Los invito a leer la documentación .
Si desea ordenar por la segunda columna, puede hacer esto:
a.sort(compareSecondColumn); function compareSecondColumn(a, b) { if (a[1] === b[1]) { return 0; } else { return (a[1] < b[1]) ? -1 : 1; } }fuente
<o>. De todos modos, me gusta la actualización :)El mejor enfoque sería utilizar lo siguiente, ya que puede haber valores repetitivos en la primera columna.
var arr = [[12, 'AAA'], [12, 'BBB'], [12, 'CCC'],[28, 'DDD'], [18, 'CCC'],[12, 'DDD'],[18, 'CCC'],[28, 'DDD'],[28, 'DDD'],[58, 'BBB'],[68, 'BBB'],[78, 'BBB']]; arr.sort(function(a,b) { return a[0]-b[0] });fuente
prueba esto
//WITH FIRST COLUMN arr = arr.sort(function(a,b) { return a[0] - b[0]; }); //WITH SECOND COLUMN arr = arr.sort(function(a,b) { return a[1] - b[1]; });Nota: La respuesta original usó mayor que (>) en lugar de menos (-), que es a lo que los comentarios se refieren como incorrectos.
fuente
Usando la función de flecha y ordenando por el segundo campo de cadena
var a = [[12, 'CCC'], [58, 'AAA'], [57, 'DDD'], [28, 'CCC'],[18, 'BBB']]; a.sort((a, b) => a[1].localeCompare(b[1])); console.log(a)fuente
Si eres como yo, no querrás cambiar cada índice cada vez que quieras cambiar la columna por la que estás ordenando.
function sortByColumn(a, colIndex){ a.sort(sortFunction); function sortFunction(a, b) { if (a[colIndex] === b[colIndex]) { return 0; } else { return (a[colIndex] < b[colIndex]) ? -1 : 1; } } return a; } var sorted_a = sortByColumn(a, 2);fuente
Nada especial, solo se ahorra el costo que se necesita para devolver un valor en cierto índice de una matriz.
function sortByCol(arr, colIndex){ arr.sort(sortFunction) function sortFunction(a, b) { a = a[colIndex] b = b[colIndex] return (a === b) ? 0 : (a < b) ? -1 : 1 } } // Usage var a = [[12, 'AAA'], [58, 'BBB'], [28, 'CCC'],[18, 'DDD']] sortByCol(a, 0) console.log(JSON.stringify(a)) // "[[12,"AAA"],[18,"DDD"],[28,"CCC"],[58,"BBB"]]"fuente
a[colIndex]una y otra vez, pero lo estoy captando aquía = a[colIndex]. Es más eficiente. 2. Estoy usando un sabor diferente deif, haciéndolo más corto. 3. No regresoarrcomo resultado de lasortByColfunción, lo que significa que mi función no se puede usar para crear otra referencia. ¡Espero eso ayude!en una línea:
var cars = [ {type:"Volvo", year:2016}, {type:"Saab", year:2001}, {type:"BMW", year:2010} ] function myFunction() { return cars.sort((a, b)=> a.year - b.year) }fuente
Si desea ordenar según la primera columna (que contiene el valor numérico ), intente esto:
arr.sort(function(a,b){ return a[0]-b[0] })Si desea ordenar según la segunda columna (que contiene un valor de cadena ), intente esto:
arr.sort(function(a,b){ return a[1].charCodeAt(0)-b[1].charCodeAt(0) })PD para el segundo caso, debe comparar entre sus valores ASCII.
Espero que esto ayude.
fuente
Como mi caso de uso involucra docenas de columnas, expandí un poco la respuesta de @jahroy. (también me acabo de dar cuenta de que @ charles-clayton tenía la misma idea).
Paso el parámetro por el que quiero ordenar, y la función de ordenación se redefine con el índice deseado para que se lleve a cabo la comparación.
var ID_COLUMN=0 var URL_COLUMN=1 findings.sort(compareByColumnIndex(URL_COLUMN)) function compareByColumnIndex(index) { return function(a,b){ if (a[index] === b[index]) { return 0; } else { return (a[index] < b[index]) ? -1 : 1; } } }fuente
De pie sobre los hombros de charles-clayton y @ vikas-gautam, agregué la prueba de cuerdas que se necesita si una columna tiene cuerdas como en OP.
return isNaN(a-b) ? (a === b) ? 0 : (a < b) ? -1 : 1 : a-b ;La prueba
isNaN(a-b)determina si las cadenas no se pueden convertir en números. Si pueden, laa-bprueba es válida.Tenga en cuenta que ordenar una columna de tipos mixtos siempre dará un resultado entretenido ya que la prueba de igualdad estricta
(a === b)siempre devolverá falso. Ver MDN aquíEste es el script completo con la prueba de Logger, usando Google Apps Script.
function testSort(){ function sortByCol(arr, colIndex){ arr.sort(sortFunction); function sortFunction(a, b) { a = a[colIndex]; b = b[colIndex]; return isNaN(a-b) ? (a === b) ? 0 : (a < b) ? -1 : 1 : a-b ; // test if text string - ie cannot be coerced to numbers. // Note that sorting a column of mixed types will always give an entertaining result as the strict equality test will always return false // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness } } // Usage var a = [ [12,'12', 'AAA'], [12,'11', 'AAB'], [58,'120', 'CCC'], [28,'08', 'BBB'], [18,'80', 'DDD'], ] var arr1 = a.map(function (i){return i;}).sort(); // use map to ensure tests are not corrupted by a sort in-place. Logger.log("Original unsorted:\n " + JSON.stringify(a)); Logger.log("Vanilla sort:\n " + JSON.stringify(arr1)); sortByCol(a, 0); Logger.log("By col 0:\n " + JSON.stringify(a)); sortByCol(a, 1); Logger.log("By col 1:\n " + JSON.stringify(a)); sortByCol(a, 2); Logger.log("By col 2:\n " + JSON.stringify(a)); /* vanilla sort returns " [ [12,"11","AAB"], [12,"12","AAA"], [18,"80","DDD"], [28,"08","BBB"], [58,"120","CCC"] ] if col 0 then returns "[ [12,'12',"AAA"], [12,'11', 'AAB'], [18,'80',"DDD"], [28,'08',"BBB"], [58,'120',"CCC"] ]" if col 1 then returns "[ [28,'08',"BBB"], [12,'11', 'AAB'], [12,'12',"AAA"], [18,'80',"DDD"], [58,'120',"CCC"], ]" if col 2 then returns "[ [12,'12',"AAA"], [12,'11', 'AAB'], [28,'08',"BBB"], [58,'120',"CCC"], [18,'80',"DDD"], ]" */ }fuente