2623 votes

Tri des objets dans un tableau par la valeur d'un champ en JavaScript

Dire que 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 trier par la valeur de last_nom en JavaScript?

Je sais à propos de sort(a,b), mais qui semble seulement à travailler sur des chaînes de caractères et des nombres. Ai-je besoin d'ajouter une méthode toString de mes objets?

3748voto

Wogan Points 9176

Il est assez facile d'écrire votre 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);

817voto

Ege Özcan Points 2561

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

function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a,b) {
        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 ceci:

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

...et au travail quand vous n':

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

Plusieurs Paramètres

Vous pouvez utiliser la fonction ci-dessous pour générer des fonctions de tri avec de multiples 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 ceci:

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

Ajouter Au Prototype

(Mise en œuvre qui est juste en dessous est inspiré de Mike R's réponse)

Je ne recommanderais pas la modification d'un objet natif prototype, mais juste pour donner un exemple, donc vous pouvez l'appliquer sur vos propres objets (Pour les environnements qui le prennent en charge, vous pouvez également utiliser l'Objet.defineProperty comme indiqué dans la section suivante, qui n'a pas les effets secondaires négatifs de jongler avec un modèle prototype de l'objet, comme décrit dans la dernière partie)

Prototype de la mise en œuvre serait quelque chose comme ce qui suit (Voici un exemple):

//Don't just copy-paste this code. You will break the "for-in" loops
!function() {
    function _dynamicSortMultiple(attr) {
       /* dynamicSortMultiple function body comes here */
    }
    function _dynamicSort(property) {
        /* dynamicSort function body comes here */
    }
    Array.prototype.sortBy = function() {
        return this.sort(_dynamicSortMultiple.apply(null, arguments));
    }
}();

La Bonne Façon De L'Ajouter À La Prototype

Si vous ciblez IE v9.0 et puis, comme je l'ai mentionné précédemment, l'utilisation de l'Objet.defineProperty comme ceci (exemple):

//Won't work below IE9, but totally safe otherwise
!function() {
    function _dynamicSortMultiple(attr) {
       /* dynamicSortMultiple function body comes here */
    }
    function _dynamicSort(property) {
        /* dynamicSort function body comes here */
    }
    Object.defineProperty(Array.prototype, "sortBy", {
        enumerable: false,
        writable: true,
        value: function() {
            return this.sort(_dynamicSortMultiple.apply(null, arguments));
        }
    });
}();

Tous ceux prototype plaisir permet ceci:

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

Vous Devriez Lire Ce

Si vous utilisez le direct prototype de la méthode d'accès (Objet.defineProperty est très bien) et d'autres code ne vérifie pas hasOwnProperty, chatons meurent! Ok, pour être honnête, aucun mal ne soit fait pour tout chaton vraiment, mais probablement les choses se rompre et tous les autres développeurs de votre équipe que vous détestez:

evil

Voir le dernier "SortBy"? Ouais. Pas cool. Utiliser L'Objet.defineProperty où vous le pouvez, et de laisser le Tableau.prototype seul sinon.

187voto

David Morrow Points 1162

underscore.js

l'utilisation de soulignement, de sa petite et génial...

sortBy_.sortBy(liste, itérateur, [contexte]) Renvoie une triés copie de liste, classée par ordre croissant par les résultats de l'exécution de chaque valeur par itérateur. Itérateur peut aussi être le nom de la chaîne de la propriété pour trier par (eg. 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' );

178voto

p3lim Points 99

Ne comprends pas pourquoi les gens font-il si compliqué:

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

Pour les plus strictes moteurs:

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

Swap à l'opérateur d'avoir un tri par ordre alphabétique inverse.

61voto

kennebec Points 33886

Si vous avez des noms de famille, vous pouvez trier ces 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;
});

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