Trier les objets dans un tableau par ordre alphabétique sur une propriété du tableau


201

Disons que vous avez une classe JavaScript comme celle-ci

var DepartmentFactory = function(data) {
    this.id = data.Id;
    this.name = data.DepartmentName;
    this.active = data.Active;
}

Disons que vous créez ensuite un certain nombre d'instances de cette classe et les stockez dans un tableau

var objArray = [];
objArray.push(DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));

J'aurais donc maintenant un tableau d'objets créés par DepartmentFactory. Comment pourrais-je utiliser la array.sort()méthode pour trier ce tableau d'objets par la DepartmentNamepropriété de chaque objet?

La array.sort()méthode fonctionne très bien lors du tri d'un tableau de chaînes

var myarray=["Bob", "Bully", "Amy"];
myarray.sort(); //Array now becomes ["Amy", "Bob", "Bully"]

Mais comment le faire fonctionner avec une liste d'objets?


Vous pouvez passer une fonction de tri comme premier argument à .sort ().
Paul Tomblin

2
Puisque vous utilisez DepartmentFactorycomme constructeur, créez ses objets en utilisant new DepartmentFactory, sinon le tableau sera rempli avec un tas de undefinedvaleurs.
Anurag

Réponses:


342

il faudrait faire quelque chose comme ça:

objArray.sort(function(a, b) {
    var textA = a.DepartmentName.toUpperCase();
    var textB = b.DepartmentName.toUpperCase();
    return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});

remarque: le changement de casse (en haut ou en bas) garantit un tri insensible à la casse.


3
Je suis venu à votre réponse 50 millions de fois parce que je ne me souviens jamais comment faire cela. FWIW, mon Linter m'informe toujours de "parenthèses gratuites autour de l'expression": return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;Je ne vais pas modifier votre réponse, espérant que je me souviendrai au moins de la peluche :)
Michael Tranchida

Merci pour ce Omer
Ted Fitzpatrick

Trouvé un problème avec ce code. Utilisez une combinaison de lettres minuscules et majuscules. ex. credit_card_no et City. Le code trie la liste mais les mots commençant par «c» ne sont pas regroupés.
Kedar

157

Pour prendre en charge unicode:

objArray.sort(function(a, b) {
   return a.DepartmentName.localeCompare(b.DepartmentName);
});

7
Pour une version non sensible à la casse, utilisez ce qui suit à la ligne 2:return a.DepartmentName.toLowerCase().localeCompare(b.DepartmentName.toLowerCase());
Ben Barreth

3
apprendre quelque chose de nouveau chaque jour - localeComparec'est cool et a tout le support du navigateur pour le premier argument. Pas mal!
obzenner

4
@BenBarreth il n'y a aucune raison de mettre les chaînes en minuscules. le tout localeCompareest de shunter le travail de gestion de la logique de tri et des bizarreries locales au système. Si faire un tri non sensible à la casse est normal pour les paramètres régionaux, comme c'est en anglais, cela sera fait pour vous: "Z" > 'a' // false "Z".localeCompare('a') // 1 si vous souhaitez dévier de la valeur par défaut des paramètres régionaux, vous pouvez envoyer des remplacements dans les paramètres localeset options: developer.mozilla. org / fr-US / docs / Web / JavaScript / Référence /…
Jon z

12
var DepartmentFactory = function(data) {
    this.id = data.Id;
    this.name = data.DepartmentName;
    this.active = data.Active;
}

// use `new DepartmentFactory` as given below. `new` is imporatant

var objArray = [];
objArray.push(new DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(new DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(new DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(new DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));

function sortOn(property){
    return function(a, b){
        if(a[property] < b[property]){
            return -1;
        }else if(a[property] > b[property]){
            return 1;
        }else{
            return 0;   
        }
    }
}

//objArray.sort(sortOn("id")); // because `this.id = data.Id;`
objArray.sort(sortOn("name")); // because `this.name = data.DepartmentName;`
console.log(objArray);

démo: http://jsfiddle.net/diode/hdgeH/


9
// Sorts an array of objects "in place". (Meaning that the original array will be modified and nothing gets returned.)
function sortOn (arr, prop) {
    arr.sort (
        function (a, b) {
            if (a[prop] < b[prop]){
                return -1;
            } else if (a[prop] > b[prop]){
                return 1;
            } else {
                return 0;   
            }
        }
    );
}

//Usage example:

var cars = [
        {make:"AMC",        model:"Pacer",  year:1978},
        {make:"Koenigsegg", model:"CCGT",   year:2011},
        {make:"Pagani",     model:"Zonda",  year:2006},
        ];

// ------- make -------
sortOn(cars, "make");
console.log(cars);

/* OUTPUT:
AMC         : Pacer : 1978
Koenigsegg  : CCGT  : 2011
Pagani      : Zonda : 2006
*/



// ------- model -------
sortOn(cars, "model");
console.log(cars);

/* OUTPUT:
Koenigsegg  : CCGT  : 2011
AMC         : Pacer : 1978
Pagani      : Zonda : 2006
*/



// ------- year -------
sortOn(cars, "year");
console.log(cars);

/* OUTPUT:
AMC         : Pacer : 1978
Pagani      : Zonda : 2006
Koenigsegg  : CCGT  : 2011
*/

5

DEMO

var DepartmentFactory = function(data) {
    this.id = data.Id;
    this.name = data.DepartmentName;
    this.active = data.Active;
}

var objArray = [];
objArray.push(new DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(new DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(new DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(new DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));

console.log(objArray.sort(function(a, b) { return a.name > b.name}));

2
objArray.sort( (a, b) => a.id.localeCompare(b.id, 'en', {'sensitivity': 'base'}));

Cela les trie par ordre alphabétique ET n'est pas sensible à la casse. Il est également super propre et facile à lire: D


Beaucoup plus élégant que la solution acceptée!
kano

C'est aussi la seule réponse qui mentionne 'sensitivity': 'base', ce qui fait une grande différence selon votre application selon MDN .
phantomraa

2
objArray.sort((a, b) => a.DepartmentName.localeCompare(b.DepartmentName))

1

fais-le comme ça

objArrayy.sort(function(a, b){
 var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase()
 if (nameA < nameB) //sort string ascending
  return -1
 if (nameA > nameB)
  return 1
 return 0 //default return value (no sorting)
});
console.log(objArray)

0

Voici une fonction simple que vous pouvez utiliser pour trier un tableau d'objets en fonction de leurs propriétés; peu importe si la propriété est un type de chaîne ou d'entier, cela fonctionnera.

    var cars = [
        {make:"AMC",        model:"Pacer",  year:1978},
        {make:"Koenigsegg", model:"CCGT",   year:2011},
        {make:"Pagani",     model:"Zonda",  year:2006},
    ];

    function sortObjectsByProp(objectsArr, prop, ascending = true) {
        let objectsHaveProp = objectsArr.every(object => object.hasOwnProperty(prop));
        if(objectsHaveProp)    {
            let newObjectsArr = objectsArr.slice();
            newObjectsArr.sort((a, b) => {
                if(isNaN(Number(a[prop])))  {
                    let textA = a[prop].toUpperCase(),
                        textB = b[prop].toUpperCase();
                    if(ascending)   {
                        return textA < textB ? -1 : textA > textB ? 1 : 0;
                    } else {
                        return textB < textA ? -1 : textB > textA ? 1 : 0;
                    }
                } else {
                    return ascending ? a[prop] - b[prop] : b[prop] - a[prop];
                }
            });
            return newObjectsArr;
        }
        return objectsArr;
    }

    let sortedByMake = sortObjectsByProp(cars, "make"); // returns ascending order by its make;
    let sortedByYear = sortObjectsByProp(cars, "year", false); // returns descending order by its year,since we put false as a third argument;
    console.log(sortedByMake);
    console.log(sortedByYear);


-1

Vous devez passer une fonction qui accepte deux paramètres, les compare et renvoie un nombre, donc en supposant que vous vouliez les trier par ID, vous écririez ...

objArray.sort(function(a,b) {
    return a.id-b.id;
});
// objArray is now sorted by Id

5
Il a posé des questions sur le tri par DepartmentName, et non par Id.
Paul Tomblin

J'ai essayé cela et cela ne semble pas fonctionner sur les colonnes de chaînes ... cela a fonctionné sur une colonne de date. Ce qui a fonctionné, c'est la solution de @ omer-bokhari
tsando

-2

Après avoir essayé un peu et essayé de faire le moins de boucles possible, je me suis retrouvé avec cette solution:

Démo sur codepen

const items = [
      {
        name: 'One'
      },
      {
        name: 'Maria is here'
      },
      {
        name: 'Another'
      },
      {
        name: 'Z with a z'
      },
      {
        name: '1 number'
      },
      {
        name: 'Two not a number'
      },
      {
        name: 'Third'
      },
      {
        name: 'Giant'
      }
    ];

    const sorted = items.sort((a, b) => {
      return a[name] > b[name];
    });

    let sortedAlphabetically = {};

    for(var item in sorted) {
      const firstLetter = sorted[item].name[0];
      if(sortedAlphabetically[firstLetter]) {
        sortedAlphabetically[firstLetter].push(sorted[item]);
      } else {
        sortedAlphabetically[firstLetter] = [sorted[item]]; 
      }
    }

    console.log('sorted', sortedAlphabetically);

-3

Une réponse simple:

objArray.sort(function(obj1, obj2) {
   return obj1.DepartmentName > obj2.DepartmentName;
});

Manière ES6:

objArray.sort((obj1, obj2) => {return obj1.DepartmentName > obj2.DepartmentName};

Si vous devez le mettre en minuscules / majuscules, etc., faites-le et stockez le résultat dans une variable que comparez cette variable. Exemple:

objArray.sort((obj1, obj2) => {
   var firstObj = obj1.toLowerCase();
   var secondObj = obj2.toLowerCase();
   return firstObj.DepartmentName > secondObj.DepartmentName;
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.