Tri d'un tableau d'objets par valeur de propriété

1335

J'ai les objets suivants en utilisant AJAX et les ai stockés dans un tableau:

var homes = [
    {
        "h_id": "3",
        "city": "Dallas",
        "state": "TX",
        "zip": "75201",
        "price": "162500"
    }, {
        "h_id": "4",
        "city": "Bevery Hills",
        "state": "CA",
        "zip": "90210",
        "price": "319250"
    }, {
        "h_id": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

Comment créer une fonction pour trier les objets par la pricepropriété dans l' ordre croissant ou décroissant en utilisant uniquement JavaScript?

TomHankers
la source
le moyen le plus rapide consiste à utiliser le module de tableau de tri isomorphe qui fonctionne nativement dans le navigateur et le nœud, prenant en charge tout type d'entrée, les champs calculés et les ordres de tri personnalisés.
Lloyd

Réponses:

1674

Trier les maisons par prix en ordre croissant:

homes.sort(function(a, b) {
    return parseFloat(a.price) - parseFloat(b.price);
});

Ou après la version ES6:

homes.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));

Une documentation peut être trouvée ici .

Stobor
la source
184
Vous pouvez utiliser string1.localeCompare(string2)pour la comparaison des chaînes
bradvido
62
Gardez à l'esprit que la localeCompare()casse est insensible . Si vous souhaitez respecter la casse, vous pouvez utiliser (string1 > string2) - (string1 < string2). Les valeurs booléennes sont contraintes à un entier 0 et 1 pour calculer la différence.
Don Kirkby
2
Merci pour la mise à jour, @Pointy, je ne me souviens pas avoir rencontré ce problème, mais peut-être que le comportement a changé au cours des deux dernières années. Quoi qu'il en soit, la localeCompare()documentation montre que vous pouvez indiquer explicitement si vous souhaitez respecter la casse, le tri numérique et d'autres options.
Don Kirkby
2
@ sg28 Je pense que vous avez mal compris l'explication de MDN. Il ne dit pas que la fonction de tri n'est pas fiable , il dit qu'elle n'est pas stable . Je comprends pourquoi cela peut prêter à confusion, mais cela ne veut pas dire qu'il ne convient pas à l'utilisation. Dans le contexte des algorithmes de tri, le terme stable a une signification spécifique - les éléments "égaux" dans la liste sont triés dans le même ordre que dans l'entrée . Cela n'a aucun rapport avec l'idée de code instable (c'est-à-dire pas encore prêt à l'emploi).
Stobor
1
Si vous souhaitez trier par une chaîne spécifique, par exemple par ville, vous pouvez utiliser: this.homes.sort ((current, next) => {return current.city.localeCompare (next.city)});
Jorge Valvert
675

Voici une version plus flexible, qui vous permet de créer des fonctions de tri réutilisables et de trier par n'importe quel champ.

const sort_by = (field, reverse, primer) => {

  const key = primer ?
    function(x) {
      return primer(x[field])
    } :
    function(x) {
      return x[field]
    };

  reverse = !reverse ? 1 : -1;

  return function(a, b) {
    return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
  }
}


//Now you can sort by any field at will...

const homes=[{h_id:"3",city:"Dallas",state:"TX",zip:"75201",price:"162500"},{h_id:"4",city:"Bevery Hills",state:"CA",zip:"90210",price:"319250"},{h_id:"5",city:"New York",state:"NY",zip:"00010",price:"962500"}];

// Sort by price high to low
console.log(homes.sort(sort_by('price', true, parseInt)));

// Sort by city, case-insensitive, A-Z
console.log(homes.sort(sort_by('city', false, (a) =>  a.toUpperCase()
)));

Triptyque
la source
7
nickb - vous avez mal lu le code. sort_bys'exécute dans O (1) et renvoie une fonction utilisée par le tri intégré (O (N log N)) pour comparer les éléments d'une liste. La complexité totale est O (n log n) * O (1) qui se réduit à O (n log n), ou identique à un tri rapide.
Triptyque
1
Un problème que j'ai avec ceci est qu'avec reverse = false, il triera les nombres comme 1,2,3,4 ... mais les chaînes comme z, y, x ...
Abby
4
Une petite amélioration:var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }
ErikE
6
Bien que [1,-1][+!!reverse]ça a l'air cool, c'est une chose horrible à faire. Si un utilisateur ne peut pas appeler votre méthode correctement, punissez-le, n'essayez pas de lui donner un sens, quoi qu'il arrive.
Ingo Bürk
2
Ne serait-il pas préférable de préparer les données source, cela entraînerait une analyse consécutive alors que les données source ont clairement besoin d'être peaufinées.
Gerrit Brink
134

Pour le trier, vous devez créer une fonction de comparaison prenant deux arguments. Appelez ensuite la fonction de tri avec cette fonction de comparaison comme suit:

// a and b are object elements of your array
function mycomparator(a,b) {
  return parseInt(a.price, 10) - parseInt(b.price, 10);
}
homes.sort(mycomparator);

Si vous souhaitez trier par ordre croissant, changez les expressions de chaque côté du signe moins.

Ricardo Marimon
la source
3
Et voici une référence qui explique réellement le sujet au lieu de dire "c'est trop compliqué, vous ne le comprendrez pas de toute façon": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Roland Illig
51

pour le tri des chaînes au cas où quelqu'un en aurait besoin,

const dataArr = {

  "hello": [{
    "id": 114,
    "keyword": "zzzzzz",
    "region": "Sri Lanka",
    "supportGroup": "administrators",
    "category": "Category2"
  }, {
    "id": 115,
    "keyword": "aaaaa",
    "region": "Japan",
    "supportGroup": "developers",
    "category": "Category2"
  }]

};
const sortArray = dataArr['hello'];

console.log(sortArray.sort((a, b) => {
  if (a.region < b.region)
    return -1;
  if (a.region > b.region)
    return 1;
  return 0;
}));

Ishan Liyanage
la source
38

Si vous avez un navigateur compatible ES6, vous pouvez utiliser:

La différence entre l'ordre de tri croissant et décroissant est le signe de la valeur renvoyée par votre fonction de comparaison:

var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price));
var descending = homes.sort((a, b) => Number(b.price) - Number(a.price));

Voici un extrait de code fonctionnel:

var homes = [{
  "h_id": "3",
  "city": "Dallas",
  "state": "TX",
  "zip": "75201",
  "price": "162500"
}, {
  "h_id": "4",
  "city": "Bevery Hills",
  "state": "CA",
  "zip": "90210",
  "price": "319250"
}, {
  "h_id": "5",
  "city": "New York",
  "state": "NY",
  "zip": "00010",
  "price": "962500"
}];

homes.sort((a, b) => Number(a.price) - Number(b.price));
console.log("ascending", homes);

homes.sort((a, b) => Number(b.price) - Number(a.price));
console.log("descending", homes);

Stephen Quan
la source
22

Vous voulez le trier en Javascript, non? Ce que vous voulez, c'est la sort()fonction . Dans ce cas, vous devez écrire une fonction de comparaison et la transmettre à sort(), donc quelque chose comme ceci:

function comparator(a, b) {
    return parseInt(a["price"], 10) - parseInt(b["price"], 10);
}

var json = { "homes": [ /* your previous data */ ] };
console.log(json["homes"].sort(comparator));

Votre comparateur prend un de chacun des hachages imbriqués à l'intérieur du tableau et décide lequel est le plus élevé en vérifiant le champ "prix".

Tim Gilbert
la source
21

Je recommande GitHub: Array sortBy - une meilleure implémentation de sortByméthode qui utilise la transformation Schwartzian

Mais pour l'instant nous allons essayer cette approche Gist: sortBy-old.js .
Créons une méthode pour trier les tableaux pouvant arranger les objets selon une propriété.

Création de la fonction de tri

var sortBy = (function () {
  var toString = Object.prototype.toString,
      // default parser function
      parse = function (x) { return x; },
      // gets the item to be sorted
      getItem = function (x) {
        var isObject = x != null && typeof x === "object";
        var isProp = isObject && this.prop in x;
        return this.parser(isProp ? x[this.prop] : x);
      };

  /**
   * Sorts an array of elements.
   *
   * @param  {Array} array: the collection to sort
   * @param  {Object} cfg: the configuration options
   * @property {String}   cfg.prop: property name (if it is an Array of objects)
   * @property {Boolean}  cfg.desc: determines whether the sort is descending
   * @property {Function} cfg.parser: function to parse the items to expected type
   * @return {Array}
   */
  return function sortby (array, cfg) {
    if (!(array instanceof Array && array.length)) return [];
    if (toString.call(cfg) !== "[object Object]") cfg = {};
    if (typeof cfg.parser !== "function") cfg.parser = parse;
    cfg.desc = !!cfg.desc ? -1 : 1;
    return array.sort(function (a, b) {
      a = getItem.call(cfg, a);
      b = getItem.call(cfg, b);
      return cfg.desc * (a < b ? -1 : +(a > b));
    });
  };

}());

Définition de données non triées

var data = [
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90,  tip: 0,   type: "Tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0,   type: "cash"},
  {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0,   type: "Cash"}
];

En l'utilisant

Organiser le tableau, par "date"asString

// sort by @date (ascending)
sortBy(data, { prop: "date" });

// expected: first element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

Si vous souhaitez ignorer la casse, définissez le parserrappel:

// sort by @type (ascending) IGNORING case-sensitive
sortBy(data, {
    prop: "type",
    parser: (t) => t.toUpperCase()
});

// expected: first element
// { date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "Cash" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa" }

Si vous souhaitez convertir le "date"champ en Datetype:

// sort by @date (descending) AS Date object
sortBy(data, {
    prop: "date",
    desc: true,
    parser: (d) => new Date(d)
});

// expected: first element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

// expected: last element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

Ici, vous pouvez jouer avec le code: jsbin.com/lesebi

Grâce à @Ozesh par ses commentaires, le problème lié aux propriétés avec des valeurs de falsification a été corrigé.

jherax
la source
Cela semble rompre lorsqu'un champ est nul.
TSNev
Si vous triez des nombres et que vous rencontrez un «0» entre le tableau d'objets, vous remarquerez peut-être que le code ci-dessus se casse. Voici une solution rapide pour cela: var checkNaN = function (value) { return Number.isNaN(Number(value)) ? 0 : value; } suivi de: fonction de retour (tableau, o) { .... a = _getItem.call (o, a); a = checkNaN (a); b = _getItem.call (o, b); b = checkNaN (b); return o.desc * (a <b? -1: + (a> b)); });
Ozesh
18

Utilisez lodash.sortBy , (instructions utilisant commonjs, vous pouvez aussi simplement mettre le script include-tag pour le cdn en haut de votre html)

var sortBy = require('lodash.sortby');
// or
sortBy = require('lodash').sortBy;

Ordre décroissant

var descendingOrder = sortBy( homes, 'price' ).reverse();

Ordre croissant

var ascendingOrder = sortBy( homes, 'price' );
Evan Carroll
la source
1
Ouconst sortBy = require('lodash/sortBy'); let calendars = sortBy(calendarListResponse.items, cal => cal.summary);
mpen
Je ne sais pas si le loadash a changé récemment maintenant son nom nommé OrderByimport { orderBy } from 'lodash'; ... ... return orderBy ( rows, 'fieldName' ).reverse();
montelof
8

Cela aurait pu être réalisé grâce à une simple fonction de tri valueof () d' une ligne . Exécutez l'extrait de code ci-dessous pour voir la démo.

var homes = [
    {
        "h_id": "3",
        "city": "Dallas",
        "state": "TX",
        "zip": "75201",
        "price": "162500"
    }, {
        "h_id": "4",
        "city": "Bevery Hills",
        "state": "CA",
        "zip": "90210",
        "price": "319250"
    }, {
        "h_id": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

console.log("To sort descending/highest first, use operator '<'");

homes.sort(function(a,b) { return a.price.valueOf() < b.price.valueOf();});

console.log(homes);

console.log("To sort ascending/lowest first, use operator '>'");

homes.sort(function(a,b) { return a.price.valueOf() > b.price.valueOf();});

console.log(homes);

Ajay Singh
la source
8

Je suis un peu en retard pour la fête mais voici ma logique de tri.

function getSortedData(data, prop, isAsc) {
    return data.sort((a, b) => {
        return (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1)
    });
}
Santosh
la source
6

Bien que je sache que l'OP voulait trier un tableau de nombres, cette question a été marquée comme la réponse à des questions similaires concernant les chaînes. À ce fait, les réponses ci-dessus ne considèrent pas le tri d'un tableau de texte où la casse est importante. La plupart des réponses prennent les valeurs de chaîne et les convertissent en majuscules / minuscules, puis trient d'une manière ou d'une autre. Les exigences auxquelles j'adhère sont simples:

  • Tri alphabétique AZ
  • Les valeurs majuscules du même mot doivent précéder les valeurs minuscules
  • Les mêmes valeurs de lettre (A / a, B / b) doivent être regroupées

Ce que j'attends, c'est [ A, a, B, b, C, c ]que les réponses ci-dessus reviennent A, B, C, a, b, c. En fait, je me suis gratté la tête plus longtemps que je ne le souhaitais (c'est pourquoi je poste ceci dans l'espoir que cela aidera au moins une autre personne). Alors que deux utilisateurs mentionnent la localeComparefonction dans les commentaires pour la réponse marquée, je ne l'ai vu qu'après être tombé sur la fonction en cherchant autour. Après avoir lu la documentation String.prototype.localeCompare (), j'ai pu trouver ceci:

var values = [ "Delta", "charlie", "delta", "Charlie", "Bravo", "alpha", "Alpha", "bravo" ];
var sorted = values.sort((a, b) => a.localeCompare(b, undefined, { caseFirst: "upper" }));
// Result: [ "Alpha", "alpha", "Bravo", "bravo", "Charlie", "charlie", "Delta", "delta" ]

Cela indique à la fonction de trier les valeurs majuscules avant les valeurs minuscules. Le deuxième paramètre de la localeComparefonction est de définir les paramètres régionaux, mais si vous le laissez, undefinedil détermine automatiquement les paramètres régionaux pour vous.

Cela fonctionne également pour le tri d'un tableau d'objets:

var values = [
    { id: 6, title: "Delta" },
    { id: 2, title: "charlie" },
    { id: 3, title: "delta" },
    { id: 1, title: "Charlie" },
    { id: 8, title: "Bravo" },
    { id: 5, title: "alpha" },
    { id: 4, title: "Alpha" },
    { id: 7, title: "bravo" }
];
var sorted = values
    .sort((a, b) => a.title.localeCompare(b.title, undefined, { caseFirst: "upper" }));
Mitchell Skurnik
la source
5

Vous pouvez utiliser la sortméthode JavaScript avec une fonction de rappel:

function compareASC(homeA, homeB)
{
    return parseFloat(homeA.price) - parseFloat(homeB.price);
}

function compareDESC(homeA, homeB)
{
    return parseFloat(homeB.price) - parseFloat(homeA.price);
}

// Sort ASC
homes.sort(compareASC);

// Sort DESC
homes.sort(compareDESC);
John G
la source
4

Voici l'aboutissement de toutes les réponses ci-dessus.

Validation du violon: http://jsfiddle.net/bobberino/4qqk3/

var sortOn = function (arr, prop, reverse, numeric) {

    // Ensure there's a property
    if (!prop || !arr) {
        return arr
    }

    // Set up sort function
    var sort_by = function (field, rev, primer) {

        // Return the required a,b function
        return function (a, b) {

            // Reset a, b to the field
            a = primer(a[field]), b = primer(b[field]);

            // Do actual sorting, reverse as needed
            return ((a < b) ? -1 : ((a > b) ? 1 : 0)) * (rev ? -1 : 1);
        }

    }

    // Distinguish between numeric and string to prevent 100's from coming before smaller
    // e.g.
    // 1
    // 20
    // 3
    // 4000
    // 50

    if (numeric) {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to a string.
            // - Replace any non numeric characters.
            // - Parse as float to allow 0.02 values.
            return parseFloat(String(a).replace(/[^0-9.-]+/g, ''));

        }));
    } else {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to string.
            return String(a).toUpperCase();

        }));
    }


}
bob
la source
pouvez-vous s'il vous plaît expliquer quelle est la signification d'avoir * (rev? -1: 1);
TechTurtle
C'est pour inverser l'ordre (ascendant vs descendant) la partie rev retourne simplement les résultats normaux lorsque l'argument rev est vrai. Sinon, il ne fera que multiplier par 1, ce qui ne fait rien, une fois défini, il multipliera le résultat par -1, inversant ainsi le résultat.
bob
3

Pour trier un tableau, vous devez définir une fonction de comparaison. Cette fonction sera toujours différente selon le modèle ou l'ordre de tri souhaité (c'est-à-dire croissant ou décroissant).

Laissez créer certaines fonctions qui trient un tableau croissant ou décroissant et qui contiennent un objet ou une chaîne ou des valeurs numériques.

function sorterAscending(a,b) {
    return a-b;
}

function sorterDescending(a,b) {
    return b-a;
}

function sorterPriceAsc(a,b) {
    return parseInt(a['price']) - parseInt(b['price']);
}

function sorterPriceDes(a,b) {
    return parseInt(b['price']) - parseInt(b['price']);
}

Trier les nombres (par ordre alphabétique et croissant):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();

Trier les nombres (par ordre alphabétique et décroissant):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
fruits.reverse();

Trier les nombres (numériquement et croissant):

var points = [40,100,1,5,25,10];
points.sort(sorterAscending());

Trier les nombres (numériquement et décroissant):

var points = [40,100,1,5,25,10];
points.sort(sorterDescending());

Comme ci-dessus, utilisez la méthode sorterPriceAsc et sorterPriceDes avec votre tableau avec la clé souhaitée.

homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())
Lalit Kumar Maurya
la source
3

J'ai également travaillé avec une sorte de classement et un tri sur plusieurs champs:

arr = [
    {type:'C', note:834},
    {type:'D', note:732},
    {type:'D', note:008},
    {type:'F', note:474},
    {type:'P', note:283},
    {type:'P', note:165},
    {type:'X', note:173},
    {type:'Z', note:239},
];

arr.sort(function(a,b){        
    var _a = ((a.type==='C')?'0':(a.type==='P')?'1':'2');
    _a += (a.type.localeCompare(b.type)===-1)?'0':'1';
    _a += (a.note>b.note)?'1':'0';
    var _b = ((b.type==='C')?'0':(b.type==='P')?'1':'2');
    _b += (b.type.localeCompare(a.type)===-1)?'0':'1';
    _b += (b.note>a.note)?'1':'0';
    return parseInt(_a) - parseInt(_b);
});

Résultat

[
    {"type":"C","note":834},
    {"type":"P","note":165},
    {"type":"P","note":283},
    {"type":"D","note":8},
    {"type":"D","note":732},
    {"type":"F","note":474},
    {"type":"X","note":173},
    {"type":"Z","note":239}
]
Rodolfo Jorge Nemer Nogueira
la source
3

Bien que ce soit un peu exagéré de simplement trier un seul tableau, cette fonction prototype permet de trier les tableaux Javascript par n'importe quelle clé, dans l'ordre croissant ou décroissant, y compris les clés imbriquées , en utilisant la dotsyntaxe.

(function(){
    var keyPaths = [];

    var saveKeyPath = function(path) {
        keyPaths.push({
            sign: (path[0] === '+' || path[0] === '-')? parseInt(path.shift()+1) : 1,
            path: path
        });
    };

    var valueOf = function(object, path) {
        var ptr = object;
        for (var i=0,l=path.length; i<l; i++) ptr = ptr[path[i]];
        return ptr;
    };

    var comparer = function(a, b) {
        for (var i = 0, l = keyPaths.length; i < l; i++) {
            aVal = valueOf(a, keyPaths[i].path);
            bVal = valueOf(b, keyPaths[i].path);
            if (aVal > bVal) return keyPaths[i].sign;
            if (aVal < bVal) return -keyPaths[i].sign;
        }
        return 0;
    };

    Array.prototype.sortBy = function() {
        keyPaths = [];
        for (var i=0,l=arguments.length; i<l; i++) {
            switch (typeof(arguments[i])) {
                case "object": saveKeyPath(arguments[i]); break;
                case "string": saveKeyPath(arguments[i].match(/[+-]|[^.]+/g)); break;
            }
        }
        return this.sort(comparer);
    };    
})();

Usage:

var data = [
    { name: { first: 'Josh', last: 'Jones' }, age: 30 },
    { name: { first: 'Carlos', last: 'Jacques' }, age: 19 },
    { name: { first: 'Carlos', last: 'Dante' }, age: 23 },
    { name: { first: 'Tim', last: 'Marley' }, age: 9 },
    { name: { first: 'Courtney', last: 'Smith' }, age: 27 },
    { name: { first: 'Bob', last: 'Smith' }, age: 30 }
]

data.sortBy('age'); // "Tim Marley(9)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Bob Smith(30)"

Tri par propriétés imbriquées avec syntaxe à points ou syntaxe de tableau:

data.sortBy('name.first'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy(['name', 'first']); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

Tri par plusieurs clés:

data.sortBy('name.first', 'age'); // "Bob Smith(30)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy('name.first', '-age'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

Vous pouvez bifurquer le dépôt: https://github.com/eneko/Array.sortBy

Eneko Alonso
la source
J'aime beaucoup cette réponse à cause de sa sortBysyntaxe concise. Simple à utiliser - même avec des champs imbriqués - tout en conservant une excellente lisibilité du code. Je vous remercie!
Manfred Urban
3

Avec ECMAScript 6, la réponse de StoBor peut être encore plus concise:

homes.sort((a, b) => a.price - b.price)
CracyD
la source
3

Ordre de prix décroissant:

homes.sort((x,y) => {return y.price - x.price})

Ordre de prix croissant:

homes.sort((x,y) => {return x.price - y.price})
Arushi Bajpai
la source
2

Si vous utilisez Underscore.js , essayez sortBy:

// price is of an integer type
_.sortBy(homes, "price"); 

// price is of a string type
_.sortBy(homes, function(home) {return parseInt(home.price);}); 
Vitalii Fedorenko
la source
2

Voici une version légèrement modifiée de l'implémentation élégante du livre "JavaScript: The Good Parts".

REMARQUE : cette version de byest stable . Il conserve l'ordre du premier tri lors de l'exécution du tri chaîné suivant.

Je lui ai ajouté un isAscendingparamètre. Il a également été converti aux ES6normes et aux pièces «plus récentes» recommandées par l'auteur.

Vous pouvez trier par ordre croissant ou décroissant et par chaîne en fonction de plusieurs propriétés.

const by = function (name, minor, isAscending=true) {
    const reverseMutliplier = isAscending ? 1 : -1;
    return function (o, p) {
        let a, b;
        let result;
        if (o && p && typeof o === "object" && typeof p === "object") {
            a = o[name];
            b = p[name];
            if (a === b) {
                return typeof minor === 'function' ? minor(o, p) : 0;
            }
            if (typeof a === typeof b) {
                result = a < b ? -1 : 1;
            } else {
                result = typeof a < typeof b ? -1 : 1;
            }
            return result * reverseMutliplier;
        } else {
            throw {
                name: "Error",
                message: "Expected an object when sorting by " + name
            };
        }
    };
};

let s = [
    {first: 'Joe',   last: 'Besser'},
    {first: 'Moe',   last: 'Howard'},
    {first: 'Joe',   last: 'DeRita'},
    {first: 'Shemp', last: 'Howard'},
    {first: 'Larry', last: 'Fine'},
    {first: 'Curly', last: 'Howard'}
];

// Sort by: first ascending, last ascending
s.sort(by("first", by("last")));    
console.log("Sort by: first ascending, last ascending: ", s);     // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"Besser"},     <======
//     {"first":"Joe","last":"DeRita"},     <======
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

// Sort by: first ascending, last descending
s.sort(by("first", by("last", 0, false)));  
console.log("sort by: first ascending, last descending: ", s);    // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"DeRita"},     <========
//     {"first":"Joe","last":"Besser"},     <========
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

mythicalcoder
la source
pourrions-nous trier le {"first":"Curly","last":"Howard", "property" : {"id" : "1"}}type de tableau par id?
Sahu V Kumar
oui, la fonction doit être légèrement modifiée pour intégrer un nouveau paramètre, disons, nestedName. Vous appelez ensuite byavec name = "property", nestedName = "id"
mythicalcoder
2

Pour un tableau normal de valeurs d'éléments uniquement:

function sortArrayOfElements(arrayToSort) {
    function compareElements(a, b) {
        if (a < b)
            return -1;
        if (a > b)
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareElements);
}

e.g. 1:
var array1 = [1,2,545,676,64,2,24]
output : [1, 2, 2, 24, 64, 545, 676]

var array2 = ["v","a",545,676,64,2,"24"]
output: ["a", "v", 2, "24", 64, 545, 676]

Pour un tableau d'objets:

function sortArrayOfObjects(arrayToSort, key) {
    function compareObjects(a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareObjects);
}

e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]

output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]
Umesh
la source
2

Créer une fonction et trier en fonction de l'entrée en utilisant le code ci-dessous

var homes = [{

    "h_id": "3",
    "city": "Dallas",
    "state": "TX",
    "zip": "75201",
    "price": "162500"

 }, {

    "h_id": "4",
    "city": "Bevery Hills",
    "state": "CA",
    "zip": "90210",
    "price": "319250"

 }, {

    "h_id": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

 }];

 function sortList(list,order){
     if(order=="ASC"){
        return list.sort((a,b)=>{
            return parseFloat(a.price) - parseFloat(b.price);
        })
     }
     else{
        return list.sort((a,b)=>{
            return parseFloat(b.price) - parseFloat(a.price);
        });
     }
 }

 sortList(homes,'DESC');
 console.log(homes);
Andrew Rayan
la source
2

Vous pouvez utiliser string1.localeCompare (string2) pour la comparaison de chaînes

this.myArray.sort((a,b) => { 
    return a.stringProp.localeCompare(b.stringProp);
});

Notez que localComparec'est le cas dans sensible

bradvido
la source
1

Pour trier sur plusieurs champs d'objets de tableau. Entrez votre nom de champ dans un arrproptableau comme ["a","b","c"] puis passez dans le deuxième paramètre arrsourcesource réelle que nous voulons trier.

function SortArrayobject(arrprop,arrsource){
arrprop.forEach(function(i){
arrsource.sort(function(a,b){
return ((a[i] < b[i]) ? -1 : ((a[i] > b[i]) ? 1 : 0));
});
});
return arrsource;
}
Pradip Talaviya
la source
1

Vous aurez besoin de deux fonctions

function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

Ensuite, vous pouvez l'appliquer à n'importe quelle propriété d'objet:

 data.sort((a, b) => desc(parseFloat(a.price), parseFloat(b.price)));

let data = [
    {label: "one", value:10},
    {label: "two", value:5},
    {label: "three", value:1},
];

// sort functions
function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

// DESC
data.sort((a, b) => desc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>DESCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

// ASC
data.sort((a, b) => asc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>ASCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

OzzyCzech
la source
0

J'ai récemment écrit une fonction universelle pour gérer cela pour vous si vous souhaitez l'utiliser.

/**
 * Sorts an object into an order
 *
 * @require jQuery
 *
 * @param object Our JSON object to sort
 * @param type Only alphabetical at the moment
 * @param identifier The array or object key to sort by
 * @param order Ascending or Descending
 *
 * @returns Array
 */
function sortItems(object, type, identifier, order){

    var returnedArray = [];
    var emptiesArray = []; // An array for all of our empty cans

    // Convert the given object to an array
    $.each(object, function(key, object){

        // Store all of our empty cans in their own array
        // Store all other objects in our returned array
        object[identifier] == null ? emptiesArray.push(object) : returnedArray.push(object);

    });

    // Sort the array based on the type given
    switch(type){

        case 'alphabetical':

            returnedArray.sort(function(a, b){

                return(a[identifier] == b[identifier]) ? 0 : (

                    // Sort ascending or descending based on order given
                    order == 'asc' ? a[identifier] > b[identifier] : a[identifier] < b[identifier]

                ) ? 1 : -1;

            });

            break;

        default:

    }

    // Return our sorted array along with the empties at the bottom depending on sort order
    return order == 'asc' ? returnedArray.concat(emptiesArray) : emptiesArray.concat(returnedArray);

}
Brad Bird
la source
0
homes.sort(function(a, b){
  var nameA=a.prices.toLowerCase(), nameB=b.prices.toLowerCase()
  if (nameA < nameB) //sort string ascending
    return -1 
  if (nameA > nameB)
    return 1
  return 0 //default return value (no sorting)
})
user3346960
la source
0

Salut après avoir lu cet article, j'ai fait un sortComparator pour mes besoins, avec la fonctionnalité pour comparer plus d'un attribut json, et je veux le partager avec vous.

Cette solution compare uniquement les chaînes dans l'ordre croissant, mais la solution peut être facilement étendue pour chaque attribut à prendre en charge: l'ordre inverse, d'autres types de données, l'utilisation des paramètres régionaux, la conversion, etc.

var homes = [{

    "h_id": "3",
    "city": "Dallas",
    "state": "TX",
    "zip": "75201",
    "price": "162500"

}, {

    "h_id": "4",
    "city": "Bevery Hills",
    "state": "CA",
    "zip": "90210",
    "price": "319250"

}, {

    "h_id": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

}];

// comp = array of attributes to sort
// comp = ['attr1', 'attr2', 'attr3', ...]
function sortComparator(a, b, comp) {
    // Compare the values of the first attribute
    if (a[comp[0]] === b[comp[0]]) {
        // if EQ proceed with the next attributes
        if (comp.length > 1) {
            return sortComparator(a, b, comp.slice(1));
        } else {
            // if no more attributes then return EQ
            return 0;
        }
    } else {
        // return less or great
        return (a[comp[0]] < b[comp[0]] ? -1 : 1)
    }
}

// Sort array homes
homes.sort(function(a, b) {
    return sortComparator(a, b, ['state', 'city', 'zip']);
});

// display the array
homes.forEach(function(home) {
    console.log(home.h_id, home.city, home.state, home.zip, home.price);
});

et le résultat est

$ node sort
4 Bevery Hills CA 90210 319250
5 New York NY 00010 962500
3 Dallas TX 75201 162500

et une autre sorte

homes.sort(function(a, b) {
    return sortComparator(a, b, ['city', 'zip']);
});

avec résultat

$ node sort
4 Bevery Hills CA 90210 319250
3 Dallas TX 75201 162500
5 New York NY 00010 962500
George Vrynios
la source
0

Un code simple:

    var homes = [
        {
            "h_id": "3",
            "city": "Dallas",
            "state": "TX",
            "zip": "75201",
            "price": "162500"
        }, {
            "h_id": "4",
            "city": "Bevery Hills",
            "state": "CA",
            "zip": "90210",
            "price": "319250"
        }, {
            "h_id": "5",
            "city": "New York",
            "state": "NY",
            "zip": "00010",
            "price": "962500"
        }
    ];

    let sortByPrice = homes.sort(function (a, b) 
    {
      return parseFloat(b.price) - parseFloat(a.price);
    });

    for (var i=0; i<sortByPrice.length; i++)
    {
      document.write(sortByPrice[i].h_id+' '+sortByPrice[i].city+' '
       +sortByPrice[i].state+' '
       +sortByPrice[i].zip+' '+sortByPrice[i].price);
      document.write("<br>");
    }

rashedcs
la source
0
 function compareValues(key, order = 'asc') {
  return function innerSort(a, b) {
    if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
      // property doesn't exist on either object
      return 0;
    }

    const varA = (typeof a[key] === 'string')
      ? a[key].toUpperCase() : a[key];
    const varB = (typeof b[key] === 'string')
      ? b[key].toUpperCase() : b[key];

    let comparison = 0;
    if (varA > varB) {
      comparison = 1;
    } else if (varA < varB) {
      comparison = -1;
    }
    return (
      (order === 'desc') ? (comparison * -1) : comparison
    );
  };
}

http://yazilimsozluk.com/sort-array-in-javascript-by-asc-or-desc

user1688401
la source