web-dev-qa-db-fra.com

Comment trier un tableau à 2 dimensions par valeur de colonne?

Quelqu'un peut-il m'aider à trier un tableau à 2 dimensions en JavaScript?

Il aura des données dans le format suivant:

[12, AAA]
[58, BBB]
[28, CCC]
[18, DDD]

Cela devrait ressembler à ceci une fois trié:

[12, AAA]
[18, DDD]
[28, CCC]
[58, BBB]

Donc, fondamentalement, le tri par la première colonne. 

À votre santé

51
Alex

C'est aussi simple que ça:

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;
    }
}

Je vous invite à lire la documentation .

Si vous voulez trier par la deuxième colonne, vous pouvez faire ceci:

a.sort(compareSecondColumn);

function compareSecondColumn(a, b) {
    if (a[1] === b[1]) {
        return 0;
    }
    else {
        return (a[1] < b[1]) ? -1 : 1;
    }
}
74
jahroy

La meilleure approche serait d'utiliser ce qui suit, car il peut y avoir des valeurs répétitives dans la première colonne. 

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]
});
38
Pramod Vemulapalli

essaye ça

//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];
});

Remarque: La réponse originale utilisait un plus grand que (>) au lieu de moins (-), ce que les commentaires appellent incorrect.

30
PSR

Si vous êtes un peu comme moi, vous ne voudrez pas modifier chaque index chaque fois que vous souhaitez modifier la colonne que vous triez. 

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);
8
Charles Clayton

Utilisation de la fonction de flèche et tri par le second champ de chaîne

var a = [[12, 'CCC'], [58, 'AAA'], [57, 'DDD'], [28, 'CCC'],[18, 'BBB']];
a.sort((a, b) => a[1].localeCompare(b[1]));
console.log(a)

5
Dinesh Rajan

Rien de spécial, juste économiser le coût nécessaire pour renvoyer une valeur à un certain index à partir d'un tableau.

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"]]"
3
Vikas Gautam

Debout sur les épaules de charles-clayton et de @ vikas-gautam, j'ai ajouté le test de chaîne qui est nécessaire si une colonne a des chaînes comme dans OP.

return isNaN(a-b) ? (a === b) ? 0 : (a < b) ? -1 : 1 : a-b  ;

Le test isNaN(a-b) détermine si les chaînes ne peuvent pas être forcées en chiffres. S'ils le peuvent, le test a-b est valide.

Notez que le tri d'une colonne de types mélangés donnera toujours un résultat intéressant car le test d'égalité stricte (a === b) retournera toujours faux. Voir MDN ici

Ceci est le script complet avec test Logger - utilisant 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"],
                          ]"
*/

}
0
DeeKay789

Comme mon cas d'utilisation comporte des dizaines de colonnes, j'ai développé un peu la réponse de @ jahroy. (vient aussi de se rendre compte que @ charles-clayton avait la même idée.)
Je passe le paramètre que je souhaite trier et la fonction de tri est redéfinie avec l'index souhaité pour la comparaison.

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;
    }
  }
}
0
olamotte