120 votes

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

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

Il contiendra des données au format suivant :

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

Il devrait ressembler à ceci une fois trié :

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

Donc, en gros, trier par la première colonne.

Cheers

8voto

Jared Points 114

En une seule ligne :

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

6voto

sbr_amd Points 209

Si vous voulez trier sur la base de la première colonne (qui contient numéro ), alors essayez ceci :

arr.sort(function(a,b){
  return a[0]-b[0]
})

Si vous voulez trier en fonction de la deuxième colonne (qui contient chaîne de caractères ), alors essayez ceci :

arr.sort(function(a,b){
  return a[1].charCodeAt(0)-b[1].charCodeAt(0)
})

P.S. pour le deuxième cas, vous devez comparer leurs valeurs ASCII.

3voto

Vikas Gautam Points 876

Rien de spécial, il s'agit simplement d'économiser le coût nécessaire pour renvoyer une valeur à un certain indice à 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"]]"

1voto

DeeKay789 Points 27

Debout sur les épaules de charles-clayton et @vikas-gautam, j'ai ajouté le test de la chaîne de caractères qui est nécessaire si une colonne a des chaînes de caractères 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 de caractères ne peuvent pas être converties en nombres. Si c'est le cas, la fonction a-b est valide.

Notez que le tri d'une colonne de types mixtes donnera toujours un résultat divertissant comme le test d'égalité strict (a === b) retournera toujours false. Voir MDN ici

Voici le test complet du script avec Logger - en utilisant le script de Google Apps.

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"],
                          ]"
*/

}

1voto

Mayur Points 1
Solution vary depend on column value is numeric or string. 

To sort by first column if value is numeric,
array.sort( (a, b) => a[0] - b[0]);

To sort by second column if value is numeric,
array.sort( (a, b) => a[1] - b[1]);

To sort by first column if value is string/letter,
array.sort( function(a, b) {
    const nameA = a[0].toUpperCase(); // to avoid case while sort
    const nameB = b[0].toUpperCase();
    if(nameA > nameB)
        return 1;
    else if(nameB > nameA)
        return -1;
    else
        return 0;     
})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X