Alguém pode me ajudar a classificar um Array 2 dimensional em JavaScript?
Terá dados no seguinte formato:
[12, AAA]
[58, BBB]
[28, CCC]
[18, DDD]
Deve ficar assim quando classificado:
[12, AAA]
[18, DDD]
[28, CCC]
[58, BBB]
Então, basicamente, classificando pela primeira coluna.
Felicidades
Respostas:
É simples assim:
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; } }
Eu convido você a ler a documentação .
Se quiser classificar pela segunda coluna, você pode fazer o seguinte:
a.sort(compareSecondColumn); function compareSecondColumn(a, b) { if (a[1] === b[1]) { return 0; } else { return (a[1] < b[1]) ? -1 : 1; } }
fonte
<
ou>
. De qualquer forma, gosto da atualização :)A melhor abordagem seria usar o seguinte, pois pode haver valores repetitivos na primeira coluna.
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] });
fonte
tente isso
//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]; });
Observação: a resposta original usou um maior que (>) em vez de menos (-), que é o que os comentários estão chamando de incorreto.
fonte
Usando a função de seta e classificando pelo segundo campo de string
var a = [[12, 'CCC'], [58, 'AAA'], [57, 'DDD'], [28, 'CCC'],[18, 'BBB']]; a.sort((a, b) => a[1].localeCompare(b[1])); console.log(a)
fonte
Se você for como eu, não vai querer passar pela mudança de cada índice toda vez que quiser mudar a coluna pela qual está classificando.
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);
fonte
Nada de especial, apenas economizando o custo necessário para retornar um valor em um determinado índice de uma 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"]]"
fonte
a[colIndex]
novamente e novamente, mas estou pegando aquia = a[colIndex]
. É mais eficiente. 2. Estou usando um sabor diferente deif
, tornando-o mais curto. 3. Não estou retornandoarr
como resultado desortByCol
função, o que significa que minha função não pode ser usada para criar outra referência. Espero que ajude!em uma linha:
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) }
fonte
Se você deseja classificar com base na primeira coluna (que contém o valor numérico ), tente o seguinte:
arr.sort(function(a,b){ return a[0]-b[0] })
Se você deseja classificar com base na segunda coluna (que contém o valor da string ), tente o seguinte:
arr.sort(function(a,b){ return a[1].charCodeAt(0)-b[1].charCodeAt(0) })
PS para o segundo caso, você precisa comparar entre seus valores ASCII.
Espero que isto ajude.
fonte
Como meu caso de uso envolve dezenas de colunas, expandi um pouco a resposta de @jahroy. (também acabei de perceber que @ charles-clayton teve a mesma ideia.)
Passo o parâmetro pelo qual desejo classificar e a função de classificação é redefinida com o índice desejado para a comparação.
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; } } }
fonte
Apoiado nos ombros de charles-clayton e @vikas-gautam, adicionei o teste de cordas que é necessário se uma coluna tem cordas como em OP.
return isNaN(a-b) ? (a === b) ? 0 : (a < b) ? -1 : 1 : a-b ;
O teste
isNaN(a-b)
determina se as strings não podem ser transformadas em números. Se eles podem, então oa-b
teste é válido.Observe que classificar uma coluna de tipos mistos sempre fornecerá um resultado divertido, pois o teste de igualdade estrito
(a === b)
sempre retornará falso. Veja MDN aquiEste é o script completo com teste 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"], ]" */ }
fonte