3591 votes

Trier un tableau d'objets en fonction de la valeur d'une propriété de type chaîne de caractères

J'ai un tableau d'objets JavaScript :

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

Comment puis-je les trier en fonction de la valeur de last_nom en JavaScript ?

Je connais sort(a,b) mais cela ne semble fonctionner que pour les chaînes de caractères et les nombres. Dois-je ajouter un toString() à mes objets ?

7 votes

Ce script vous permet justement de le faire, à moins que vous ne souhaitiez écrire votre propre fonction de comparaison ou de tri : thomasfrank.se/trier_les_choses.html

0 votes

Le moyen le plus rapide est d'utiliser l'isomorphe tri-array qui fonctionne nativement dans le navigateur et dans le nœud, et qui prend en charge tous les types d'entrées, les champs calculés et les ordres de tri personnalisés.

9 votes

Pls objs.sort((a, b) => a.last_nom > b.last_nom && 1 || -1)

4981voto

Wogan Points 9176

Il est assez facile d'écrire sa propre fonction de comparaison :

function compare( a, b ) {
  if ( a.last_nom < b.last_nom ){
    return -1;
  }
  if ( a.last_nom > b.last_nom ){
    return 1;
  }
  return 0;
}

objs.sort( compare );

Ou en ligne ( c/o Marco Demaio ):

objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0))

Ou simplifiée pour les valeurs numériques ( c/o Andre Figueiredo ):

objs.sort((a,b) => a.last_nom - b.last_nom); // b - a for reverse sort

532 votes

Ou en ligne : objs.sort(function(a,b) {return (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0);} ) ;

40 votes

252 votes

return a.last_nom.localeCompare(b.last_nom) fonctionnera également.

1012voto

Ege Özcan Points 2561

Vous pouvez également créer une fonction de tri dynamique qui trie les objets en fonction de la valeur que vous leur transmettez :

function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a,b) {
        /* next line works with strings and numbers, 
         * and you may want to customize it to your needs
         */
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        return result * sortOrder;
    }
}

Vous pouvez donc avoir un tableau d'objets comme celui-ci :

var People = [
    {Name: "Name", Surname: "Surname"},
    {Name:"AAA", Surname:"ZZZ"},
    {Name: "Name", Surname: "AAA"}
];

...et cela fonctionnera quand vous le ferez :

People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));

En fait, ceci répond déjà à la question. La partie ci-dessous a été rédigée parce que de nombreuses personnes m'ont contacté, se plaignant que il ne fonctionne pas avec des paramètres multiples .

Paramètres multiples

Vous pouvez utiliser la fonction ci-dessous pour générer des fonctions de tri avec plusieurs paramètres de tri.

function dynamicSortMultiple() {
    /*
     * save the arguments object as it will be overwritten
     * note that arguments object is an array-like object
     * consisting of the names of the properties to sort by
     */
    var props = arguments;
    return function (obj1, obj2) {
        var i = 0, result = 0, numberOfProperties = props.length;
        /* try getting a different result from 0 (equal)
         * as long as we have extra properties to compare
         */
        while(result === 0 && i < numberOfProperties) {
            result = dynamicSort(props[i])(obj1, obj2);
            i++;
        }
        return result;
    }
}

Ce qui vous permettrait de faire quelque chose comme ça :

People.sort(dynamicSortMultiple("Name", "-Surname"));

Sous-classement du tableau

Pour les plus chanceux d'entre nous qui peuvent utiliser ES6, qui permet d'étendre les objets natifs :

class MyArray extends Array {
    sortBy(...args) {
        return this.sort(dynamicSortMultiple(...args));
    }
}

Cela permettrait de le faire :

MyArray.from(People).sortBy("Name", "-Surname");

4 votes

C'est une bonne chose. Il existe maintenant une version Typescript de cette réponse : stackoverflow.com/a/68279093/8910547 . Restez (type) en sécurité !

217voto

David Morrow Points 1162

Underscore.js

Utilisez Underscore.js]. C'est petit et génial...

sortBy_.sortBy(list, iterator, [context]) Renvoie une copie triée de liste, classée dans l'ordre croissant des résultats de l'exécution de chaque valeur à travers l'itérateur. L'itérateur peut également être le nom de la chaîne de caractères de la propriété à trier (par exemple, la longueur).

var objs = [
  { first_nom: 'Lazslo',last_nom: 'Jamf' },
  { first_nom: 'Pig', last_nom: 'Bodine'  },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

var sortedObjs = _.sortBy(objs, 'first_nom');

20 votes

David, pourriez-vous modifier la réponse pour qu'elle dise, var sortedObjs = _.sortBy( objs, 'first_nom' ); . objs se pas se sont triées elles-mêmes à la suite de cela. La fonction retour un tableau trié. Cela serait plus explicite.

11 votes

Pour inverser le tri : var reverseSortedObjs = _.sortBy( objs, 'first_nom' ).reverse();

2 votes

Vous devez charger la librairie javascript "underscore" : <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8‌​.3/underscore-min.js‌​"> </script>

178voto

p3lim Points 99

Je ne comprends pas pourquoi les gens rendent les choses si compliquées :

objs.sort(function(a, b){
  return a.last_nom > b.last_nom;
});

Pour les moteurs plus stricts :

objs.sort(function(a, b){
  return a.last_nom == b.last_nom ? 0 : +(a.last_nom > b.last_nom) || -1;
});

Remplacez l'opérateur pour obtenir un classement par ordre alphabétique inversé.

81voto

kennebec Points 33886

Si vous avez des noms de famille en double, vous pouvez les trier par prénom.

obj.sort(function(a,b){
  if(a.last_nom< b.last_nom) return -1;
  if(a.last_nom >b.last_nom) return 1;
  if(a.first_nom< b.first_nom) return -1;
  if(a.first_nom >b.first_nom) return 1;
  return 0;
});

0 votes

@BadFeelingAboutThis que signifie retourner -1 ou 1 ? Je comprends que -1 signifie littéralement que A est inférieur à B juste par la syntaxe, mais pourquoi utiliser 1 ou -1 ? Je vois que tout le monde utilise ces nombres comme valeurs de retour, mais pourquoi ? Je vous remercie.

1 votes

@Chris22 un nombre négatif retourné signifie que b devrait venir après a dans le tableau. Si un nombre positif est renvoyé, cela signifie que a devrait venir après b . Si 0 est renvoyée, cela signifie qu'ils sont considérés comme égaux. Vous pouvez toujours consulter la documentation : developer.mozilla.org/en-US/docs/Web/JavaScript/Référence/

0 votes

@BadFeelingAboutThis merci pour l'explication et le lien. Croyez-le ou non, j'ai cherché sur Google différents bouts de code en utilisant la fonction 1, 0, -1 avant de poser cette question ici. Je ne trouvais pas les informations dont j'avais besoin.

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