Tri de la propriété d'objet par valeurs

696

Si j'ai un objet JavaScript tel que:

var list = {
  "you": 100, 
  "me": 75, 
  "foo": 116, 
  "bar": 15
};

Existe-t-il un moyen de trier les propriétés en fonction de la valeur? Pour que je me retrouve avec

list = {
  "bar": 15, 
  "me": 75, 
  "you": 100, 
  "foo": 116
};
Steerpike
la source
4
Non seulement le "tri", mais surtout le tri des nombres. Les nombres sont immunisés contre la méthode Javascripts Array.sort (), ce qui signifie que vous n'aurez pas seulement à trouver une méthode pour trier les propriétés, mais vous devrez écrire votre propre fonction pour comparer les valeurs numériques.
Sampson
106
Avant de lire les réponses: La réponse est non . L'ordre des propriétés des objets n'est pas standard dans ECMAScript. Vous ne devez jamais faire d'hypothèses sur l'ordre des éléments dans un objet JavaScript. Un objet est une collection de propriétés non ordonnée. Les réponses ci-dessous vous montrent comment "utiliser" les propriétés triées, à l'aide de tableaux, mais ne modifient jamais réellement l'ordre des propriétés des objets eux-mêmes. Donc, non, ce n'est pas possible. Même si vous créez un objet avec des propriétés pré-triées, il n'est pas garanti qu'elles s'afficheront dans le même ordre à l'avenir. Continuer à lire :).
Govind Rai
3
@GovindRai pourtant, dans les applications frontales du monde réel, nous parcourons les collections d'objets avec des ID comme clés et l'ordre est important s'il est traduit en modèles HTML. Vous dites qu'ils n'ont pas d'ordre, je dis qu'ils ont exactement l'ordre que je vois lorsque console.logging les dans le navigateur actuel. Et cet ordre peut être réorganisé. Dès que vous les parcourez, ils ont une commande.
ProblemsOfSumit
7
@GovindRai: Il existe désormais un moyen d'accéder aux propriétés dans un ordre spécifié dans la spécification. Est-ce que c'est une bonne idée? Certainement pas. :-) Mais c'est là, depuis ES2015.
TJ Crowder du
7
Visiteurs 2019: consultez cette Object.entriesréponse à peine surévaluée qui est l'état de l'art le plus propre et le plus lisible depuis ES2017: stackoverflow.com/a/37607084/245966
jakub.g

Réponses:

705

Déplacez-les vers un tableau, triez ce tableau, puis utilisez ce tableau à vos fins. Voici une solution:

var maxSpeed = {
    car: 300, 
    bike: 60, 
    motorbike: 200, 
    airplane: 1000,
    helicopter: 400, 
    rocket: 8 * 60 * 60
};
var sortable = [];
for (var vehicle in maxSpeed) {
    sortable.push([vehicle, maxSpeed[vehicle]]);
}

sortable.sort(function(a, b) {
    return a[1] - b[1];
});

//[["bike", 60], ["motorbike", 200], ["car", 300],
//["helicopter", 400], ["airplane", 1000], ["rocket", 28800]]

Une fois que vous avez le tableau, vous pouvez reconstruire l'objet à partir du tableau dans l'ordre que vous souhaitez, réalisant ainsi exactement ce que vous vous apprêtez à faire. Cela fonctionnerait dans tous les navigateurs que je connais, mais cela dépendrait d'une bizarrerie d'implémentation et pourrait casser à tout moment. Vous ne devez jamais faire d'hypothèses sur l'ordre des éléments dans un objet JavaScript.

var objSorted = {}
sortable.forEach(function(item){
    objSorted[item[0]]=item[1]
})
Nosredna
la source
24
Pouvez-vous reformuler "vous pouvez reconstruire" en "vous pouvez utiliser le tableau pour maintenir l'ordre des clés et extraire les valeurs de l'objet"? Non seulement il n'est pas standard, comme vous l'avez vous-même mentionné, cette hypothèse erronée est brisée par plus de navigateurs que Chrome aujourd'hui, il est donc préférable de ne pas encourager les utilisateurs à l'essayer.
Oleg V. Volkov
32
Voici une version plus compacte de votre code. Object.keys (maxSpeed) .sort (fonction (a, b) {return - (maxSpeed ​​[a] - maxSpeed ​​[b])});
TheBrain
6
@TheBrain: Juste pour ajouter, keys()est uniquement pris en charge par IE9 + (et d'autres navigateurs modernes), si cela vous inquiète. keys()Exclut également les propriétés énumérables de la chaîne de prototypes d'éléments (contrairement à for..in) - mais cela est généralement plus souhaitable.
MrWhite
31
_.pairstransforme un objet en [[clé1, valeur1], [clé2, valeur2]]. Ensuite, appelez sort sur cela. Appelez- _.objectle ensuite pour le retourner.
Funkodebat
2
Mon projet nécessite des clés d'objet pour une fusion propre, mais nécessite également un tri explicite car les métadonnées génèrent l'interface utilisateur. J'ai suivi une approche similaire, mais j'ai ajouté une vérification hasOwnProperty pour éviter de remonter la chaîne du prototype. Voici un bon article sur l'itération des propriétés des objets dans JS hackernoon.com/…
Nathan Agersea
416

Nous ne voulons pas dupliquer la structure de données entière, ou utiliser un tableau où nous avons besoin d'un tableau associatif.

Voici une autre façon de faire la même chose que bonna:

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted);     // bar,me,you,foo

Markus R
la source
22
Cela semble être un tri par clé, pas par valeur, ce qui n'est pas ce que la question demandait?
Michael
27
Il est trié par valeur et affiche les clés - mais nous perdons le nombre de valeurs lors de l'impression, car il imprime uniquement les clés.
Hanna
6
L'ordre des propriétés des objets n'est pas garanti en JavaScript, donc le tri doit être fait dans un tableau, pas un objet (c'est ce que vous appelez un «tableau associatif»).
Christopher Meyers
6
N'oublie pas. keysSortedest un tableau! Pas un objet!
Vert
17
Si vous ajoutez .map(key => list[key]);à la fin du tri, il renverra tout l'objet au lieu de simplement la clé
James Moran
183

Vos objets peuvent avoir n'importe quelle quantité de propriétés et vous pouvez choisir de trier par n'importe quelle propriété d'objet que vous voulez, nombre ou chaîne, si vous placez les objets dans un tableau. Considérez ce tableau:

var arrayOfObjects = [   
    {
        name: 'Diana',
        born: 1373925600000, // Mon, Jul 15 2013
        num: 4,
        sex: 'female'
    },
    {

        name: 'Beyonce',
        born: 1366832953000, // Wed, Apr 24 2013
        num: 2,
        sex: 'female'
    },
    {            
        name: 'Albert',
        born: 1370288700000, // Mon, Jun 3 2013
        num: 3,
        sex: 'male'
    },    
    {
        name: 'Doris',
        born: 1354412087000, // Sat, Dec 1 2012
        num: 1,
        sex: 'female'
    }
];

trier par date de naissance, le plus ancien en premier

// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
    return a.born - b.born;
});
console.log('by date:');
console.log(byDate);

Trier par nom

var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
    var x = a.name.toLowerCase();
    var y = b.name.toLowerCase();
    return x < y ? -1 : x > y ? 1 : 0;
});

console.log('by name:');
console.log(byName);

http://jsfiddle.net/xsM5s/16/

inorganik
la source
1
Le tri par nom ne doit pas substrsortir du premier caractère; d'autre Dianaet Debraont un ordre indéfini. De plus, votre byDatetri utilise réellement num, non born.
Lawrence Dol
Cela a l'air bien, mais notez que pour comparer des chaînes, vous pouvez simplement utiliserx.localeCompare(y)
Jemar Jones
2
@JemarJones localCompareressemble à une fonction très utile! Notez simplement qu'il ne sera pas pris en charge dans tous les navigateurs - IE 10 et moins, Safari Mobile 9 et moins.
inorganik
@inorganik Oui très bonne note pour ceux qui ont besoin de supporter ces navigateurs
Jemar Jones
1
Ceci est un tableau d'objets, qui n'est pas l'OP demandé (un objet avec plusieurs propriétés)
João Pimentel Ferreira
62

Par souci d'exhaustivité, cette fonction renvoie un tableau trié des propriétés des objets:

function sortObject(obj) {
    var arr = [];
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            arr.push({
                'key': prop,
                'value': obj[prop]
            });
        }
    }
    arr.sort(function(a, b) { return a.value - b.value; });
    //arr.sort(function(a, b) { a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
    return arr; // returns array
}

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]

Jsfiddle avec le code ci-dessus est ici . Cette solution est basée sur cet article .

Le violon mis à jour pour le tri des chaînes est ici. Vous pouvez supprimer les deux conversions .toLowerCase () supplémentaires pour une comparaison de chaîne sensible à la casse.

Stano
la source
1
Qu'en est-il d'un tableau d'objets? [{name: Will}, {name: Bill}, {name: Ben}]
Will Hancock
1
Salut Will, vous pouvez utiliser la fonction localeCompare pour cette comparaison. Ajouté à la réponse ci-dessus.
Stano
Excellente solution. Le tri de chaîne a besoin d'un retour
pfwd
@Stano Solution correcte et simple. Merci beaucoup.
Abrar Hossain
48

Présentation d'ECMAScript 2017 Object.values / Object.entries. Comme son nom l'indique, le premier regroupe toutes les valeurs d'un objet dans un tableau, et le second fait l'objet entier dans un tableau de [key, value]tableaux; L'équivalent de Python dict.values()etdict.items() .

Les fonctionnalités permettent de trier plus facilement n'importe quel hachage en un objet ordonné. Pour l'instant, seule une petite partie des plateformes JavaScript les prend en charge , mais vous pouvez l'essayer sur Firefox 47+.

let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};

let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]

let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]
kiding
la source
comment cela répond-il éventuellement au titre de la question Sorting JavaScript Object by property value? vous avez mal compris la question, je pense, puisque vous devez changer l'Objet d'origine et ne pas en créer un nouveau Tableau.
vsync
2
@vsync Cette réponse donne le même résultat que la réponse acceptée, mais avec moins de code et aucune variable temporaire.
Darren Cook
3
FWIW, cette réponse est nette et est la seule qui m'a aidé.
NetOperator Wibby
seulement en ff, pas ie, ni en chrome plus ils trient automatiquement les objets. wtf
fb
Notez simplement que cela ne préservera pas les clés.
Vael Victus
40

Une version « fléchée » de l » @marcusR réponse pour référence

var myObj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(myObj).sort((a,b) => myObj[a]-myObj[b])
alert(keysSorted);     // bar,me,you,foo

MISE À JOUR: avril 2017 - Cela renvoie un myObjobjet trié défini ci-dessus.

Object
 .keys(myObj)
 .sort((a, b) => myObj[a]-myObj[b])
 .reduce((_sortedObj, key) => ({
   ..._sortedObj, 
   [key]: myObj[key]
 }), {})

Essayez-le ici!

MISE À JOUR: octobre 2018 - version Object.entries

Object
 .entries(myObj)
 .sort()
 .reduce((_sortedObj, [k,v]) => ({
   ..._sortedObj, 
   [k]: v
 }), {})

Essayez-le ici!

Jason J. Nathan
la source
1
ne fonctionne pas pourvar myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}};
Rohanil
5
La question du PO, avec cette réponse, ne contient pas d'objets imbriqués @Rohanil Peut-être que vous voudriez poser une autre question au lieu de voter en bas. Votre objet imbriqué avec différents types a évidemment besoin de plus que ce que cette solution fournit
Jason J. Nathan
Juste une note: vos mises à jour ne fonctionneront pas réellement. Du moins pas partout et pas à cause de entries. Selon la norme, un objet est une collection de propriétés non ordonnée . Eh bien, cela signifie que si vous essayez de construire le nouvel objet après l'avoir trié par valeur de propriété ou toute autre chose, l'ordre des clés de propriété devient à nouveau indéfini. Chrome, par exemple, commande par défaut les clés de propriété, donc chaque tentative de les classer différemment est inutile. Votre seule chance est d'obtenir un "index" basé sur vos préférences de commande et de parcourir l'objet d'origine en conséquence.
ZorgoZ
Oui @ZorgoZ, vous avez raison et beaucoup de gens l'ont mentionné sur ce post. La plupart du temps, nous utilisons cette fonction comme une transformation avant de convertir en un autre type (comme JSON) ou avant une autre fonction de réduction. Si l'objectif est de muter l'objet par la suite, il peut y avoir des résultats inattendus. J'ai eu du succès avec cette fonction sur tous les moteurs.
Jason J. Nathan
Remarque: vous ne voulez pas utiliser sort()surObject.entries()
Solvitieg
36

Les objets JavaScript ne sont pas classés par définition (voir la spécification du langage ECMAScript , section 8.6). La spécification du langage ne garantit même pas que, si vous parcourez les propriétés d'un objet deux fois de suite, elles sortiront dans le même ordre la deuxième fois.

Si vous avez besoin de commandes, utilisez un tableau et la méthode Array.prototype.sort.

NickFitz
la source
4
Notez qu'il y a eu beaucoup de discussions à ce sujet. La plupart des implémentations conservent la liste dans l'ordre dans lequel les éléments ont été ajoutés. IIRC, Chrome pas. Il y avait un argument pour savoir si Chrome devrait correspondre aux autres implémentations. Ma conviction est qu'un objet JavaScript est un hachage et aucun ordre ne doit être supposé. Je crois que Python est passé par le même argument et une nouvelle liste ordonnée de type hachage a été récemment introduite. Pour la plupart des navigateurs, vous POUVEZ faire ce que vous voulez en recréant votre objet, en ajoutant des éléments par valeur triée. Mais tu ne devrais pas.
Nosredna
Éditer. Chrome maintient généralement l'ordre, mais pas toujours. Et voici le bogue Chromium pertinent: code.google.com/p/chromium/issues/detail?id=883
Nosredna
6
Ce rapport de bogue est injustifié, et ceux qui se sont fiés au comportement non documenté sont ceux qui ont les bogues. Lire la section 8.6 d'ECMASCript; il indique clairement qu '"un objet est une collection non ordonnée de propriétés". Quiconque a trouvé que cela ne semblait pas de cette façon dans quelques implémentations, puis a commencé à dépendre de ce comportement spécifique à l'implémentation, a fait une grosse erreur, et il ne devrait pas essayer de repousser le blâme. Si j'étais dans l'équipe Chrome, je marquerais ce rapport de bogue comme "non valide, WontFix".
NickFitz
8
EcmaScript 5 définit en fait l'ordre d'énumération comme étant l'ordre d'insertion - l'absence de définition est considérée comme un bogue de spécification dans ES3. Il convient de noter que la spécification EcmaScript définit un comportement que personne ne considérerait comme sain d'esprit - par exemple, le comportement de la spécification est que, dans de nombreux cas, des erreurs de syntaxe sont lancées lors de l'exécution, une utilisation incorrecte de continue, break, ++, -, const, etc. à la spécification tout moteur qui lève une exception avant d'atteindre ce code est erroné
olliej
4
@olliej - Je ne pense pas que ce soit correct. La spécification dit: "La mécanique et l'ordre d'énumération des propriétés (étape 6.a dans le premier algorithme, étape 7.a dans le second) n'est pas spécifié". C'est à la page 92 du PDF du projet final.
whitneyland
25

OK , comme vous le savez peut-être, javascript a la fonction sort () , pour trier les tableaux, mais rien pour l'objet ...

Donc, dans ce cas, nous devons en quelque sorte obtenir un tableau des clés et les trier, c'est la raison pour laquelle les API vous donnent des objets dans un tableau la plupart du temps, car Array a plus de fonctions natives pour jouer avec elles que les objets littéraux, de toute façon, la solution rapide utilise Object.key qui retourne un tableau des clés d'objet, je crée la fonction ES6 ci-dessous qui fait le travail pour vous, elle utilise les fonctions natives sort () et Reduce () en javascript:

function sortObject(obj) {
  return Object.keys(obj)
    .sort().reduce((a, v) => {
    a[v] = obj[v];
    return a; }, {});
}

Et maintenant, vous pouvez l'utiliser comme ceci:

let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);

Vérifiez le sortedMyObject et vous pouvez voir le résultat trié par des clés comme ceci:

{a: 1, b: 2, c: 3, d: 4, e: 5}

De cette façon, l'objet principal ne sera pas touché et nous obtenons en fait un nouvel objet.

Je crée également l'image ci-dessous, pour rendre les étapes de la fonction plus claires, au cas où vous auriez besoin de la modifier un peu pour qu'elle fonctionne à votre façon:

Tri d'un objet javascript par valeur de propriété

Alireza
la source
4
Ce tri par clé, pas par valeur.
ROROROOROROR
@ROROROOROROR, c'est juste une indication de la façon dont cela fonctionne car ils ne sont pas si différents, mais tout va bien, j'ajouterai également le tri par valeur
Alireza
1
Le tri par valeur est incorrect et c'est votre jeu de données. Changez c: 3pour c: 13et vous le verrez s'effondrer.
VtoCorleone
1
@VtoCorleone C'est juste une erreur de tri naturelle, 1 vient en premier, pas une faille dans l'algorithme tel que présenté.
Michael Ryan Soileau
10
var list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
};

function sortAssocObject(list) {
    var sortable = [];
    for (var key in list) {
        sortable.push([key, list[key]]);
    }
    // [["you",100],["me",75],["foo",116],["bar",15]]

    sortable.sort(function(a, b) {
        return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
    });
    // [["bar",15],["me",75],["you",100],["foo",116]]

    var orderedList = {};
    for (var idx in sortable) {
        orderedList[sortable[idx][0]] = sortable[idx][1];
    }

    return orderedList;
}

sortAssocObject(list);

// {bar: 15, me: 75, you: 100, foo: 116}
Vasil Nikolov
la source
Simple et parfait! Cela répond à la question. Merci.
Ajay Singh
L'ordre des clés n'est pas garanti en javascript, donc cela échoue pour moi si les clés sont des entiers ou similaires
ParoX
exact, ParoX. Cela ne fonctionne pas correctement lorsque la clé est de type entier.
jungwon jin
8

Mise à jour avec ES6: si votre souci est d'avoir un objet trié à parcourir (c'est pourquoi j'imagine que vous voulez que vos propriétés d'objet soient triées), vous pouvez utiliser l' objet Map .

Vous pouvez insérer vos paires (clé, valeur) dans l'ordre trié, puis faire une for..ofboucle garantira leur boucle dans l'ordre dans lequel vous les avez insérées

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// 0 = zero 
// 1 = one
julianljk
la source
De plus en ES6 (ES2015): Propriétés de l' objet n'ont l' ordre (ou il y a un moyen d'y accéder dans un ordre défini, selon votre point de vue). Si les noms de propriété sont des chaînes et ne ressemblent pas à des index de tableau, l'ordre est l'ordre dans lequel ils ont été ajoutés à l'objet. Cet ordre n'est pas spécifié pour être respecté par ou , mais il est défini pour être respecté par et les autres nouvelles méthodes d'accès aux tableaux de noms de propriété. Voilà donc une autre option. for-inObject.keysObject.getOwnPropertyNames
TJ Crowder du
Mais où est l'opération de «tri»? Ils ne sont pas du tout triés
Vert
@Green Je pense que ce que je voulais souligner ici, c'est que, avec Mapvous , vous avez en fait une structure de données qui peut stocker dans l'ordre trié (trier vos données, les parcourir et les stocker dans la carte) où, comme vous n'êtes pas assuré qu'avec objets.
julianljk
6

Underscore.js ou Lodash.js pour les tris avancés de tableaux ou d'objets

 var data={
        "models": {

            "LTI": [
                "TX"
            ],
            "Carado": [
                "A",
                "T",
                "A(пасс)",
                "A(груз)",
                "T(пасс)",
                "T(груз)",
                "A",
                "T"
            ],
            "SPARK": [
                "SP110C 2",
                "sp150r 18"
            ],
            "Autobianchi": [
                "A112"
            ]
        }
    };

    var arr=[],
        obj={};
    for(var i in data.models){
      arr.push([i, _.sortBy(data.models[i],function (el){return el;})]);
    }
    arr=_.sortBy(arr,function (el){
      return el[0];
    });
    _.map(arr,function (el){return obj[el[0]]=el[1];});
     console.log(obj);

démo

Roman Yudin
la source
6

Très court et simple!

var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
    sortedList[key] = list[key]; });
Maryam Koulaei
la source
5

Je suis la solution proposée par slebetman (allez le lire pour tous les détails), mais ajustée, puisque votre objet n'est pas imbriqué.

// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
    sort_array.push({key:key,value:list[key]});
}

// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});

// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
    var item = list[sort_array[i].key];

    // now do stuff with each item
}
va
la source
4

Trier les valeurs sans plusieurs boucles for (pour trier par les clés, changer l'index dans le rappel de tri à "0")

const list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
  };

let sorted = Object.fromEntries(
                Object.entries(list).sort( (a,b) => a[1] - b[1] )    
             ) 
console.log('Sorted object: ', sorted) 

dino4udo
la source
2

Cela pourrait être un moyen simple de le gérer comme un véritable objet ordonné. Je ne sais pas à quel point c'est lent. pourrait aussi être mieux avec une boucle while.

Object.sortByKeys = function(myObj){
  var keys = Object.keys(myObj)
  keys.sort()
  var sortedObject = Object()
  for(i in keys){
    key = keys[i]
    sortedObject[key]=myObj[key]
   }

  return sortedObject

}

Et puis j'ai trouvé cette fonction inversée à partir de: http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/

Object.invert = function (obj) {

  var new_obj = {};

  for (var prop in obj) {
    if(obj.hasOwnProperty(prop)) {
      new_obj[obj[prop]] = prop;
    }
  }

  return new_obj;
};

Donc

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)
Carson Wright
la source
2
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
  .sort((c,b) => {
    return a[b]-a[c]
  })
  .reduce((acc, cur) => {
    let o = {}
    o[cur] = a[cur]
    acc.push(o)
    return acc
   } , [])

sortie = [{p: 8}, {c: 2}, {b: 1}, {g: 1}]

Kiran Debnath
la source
2

Juste au cas où quelqu'un cherche à garder l'objet (avec des clés et des valeurs), en utilisant la référence de code par @Markus R et @James Moran commentaire, utilisez simplement:

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
                 .map(key => newO[key] = list[key]);
console.log(newO);  // {bar: 15, me: 75, you: 100, foo: 116}
esneyderp
la source
2
Vous renvoyez une mission dans ce domaine map, ce forEachserait mieux
DiegoRBaquero
2
let toSort = {a:2323, b: 14, c: 799} 
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1]) 

Production:

[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]
Remi Prasanna
la source
1

de nombreuses fonctions similaires et utiles: https://github.com/shimondoodkin/groupbyfunctions/

function sortobj(obj)
{
    var keys=Object.keys(obj);
    var kva= keys.map(function(k,i)
    {
        return [k,obj[k]];
    });
    kva.sort(function(a,b){
        if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
        return 0
    });
    var o={}
    kva.forEach(function(a){ o[a[0]]=a[1]})
    return o;
}

function sortobjkey(obj,key)
{
    var keys=Object.keys(obj);
    var kva= keys.map(function(k,i)
    {
        return [k,obj[k]];
    });
    kva.sort(function(a,b){
        k=key;      if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
        return 0
    });
    var o={}
    kva.forEach(function(a){ o[a[0]]=a[1]})
    return o;
}
Shimon Doodkin
la source
1

Objet trié par valeur (DESC)

function sortObject(list) {
  var sortable = [];
  for (var key in list) {
    sortable.push([key, list[key]]);
  }

  sortable.sort(function(a, b) {
    return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
  });

  var orderedList = {};
  for (var i = 0; i < sortable.length; i++) {
    orderedList[sortable[i][0]] = sortable[i][1];
  }

  return orderedList;
}
victorhazbun
la source
1

Voici encore un exemple:

function sortObject(obj) {
  var arr = [];
  var prop;
  for (prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      arr.push({
        'key': prop,
        'value': obj[prop]
      });
    }
  }
  arr.sort(function(a, b) {
    return a.value - b.value;
  });
  return arr; // returns array
}
var list = {
  car: 300,
  bike: 60,
  motorbike: 200,
  airplane: 1000,
  helicopter: 400,
  rocket: 8 * 60 * 60
};
var arr = sortObject(list);
console.log(arr);

Mahendra Kulkarni
la source
1
    var list = {
    "you": 100,
    "me": 75,
    "foo": 116,
    "bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
    var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
    tmpList[key] = list[key];
    delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }
Milad Aslani
la source
1

Manuscrit

La fonction suivante trie l'objet par valeur ou une propriété de la valeur. Si vous n'utilisez pas TypeScript, vous pouvez supprimer les informations de type pour les convertir en JavaScript.

/**
 * Represents an associative array of a same type.
 */
interface Dictionary<T> {
  [key: string]: T;
}

/**
 * Sorts an object (dictionary) by value or property of value and returns
 * the sorted result as a Map object to preserve the sort order.
 */
function sort<TValue>(
  obj: Dictionary<TValue>,
  valSelector: (val: TValue) => number | string,
) {
  const sortedEntries = Object.entries(obj)
    .sort((a, b) =>
      valSelector(a[1]) > valSelector(b[1]) ? 1 :
      valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
  return new Map(sortedEntries);
}

Usage

var list = {
  "one": { height: 100, weight: 15 },
  "two": { height: 75, weight: 12 },
  "three": { height: 116, weight: 9 },
  "four": { height: 15, weight: 10 },
};

var sortedMap = sort(list, val => val.height);

L'ordre des clés dans un objet JavaScript n'est pas garanti, donc je trie et renvoie le résultat en tant Mapqu'objet qui préserve l'ordre de tri.

Si vous souhaitez le reconvertir en objet, vous pouvez le faire:

var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });
orad
la source
1

l'entrée est un objet, la sortie est un objet, en utilisant la bibliothèque intégrée lodash & js, avec une option décroissante ou ascendante, et ne mute pas l'objet d'entrée

par exemple entrée et sortie

{
  "a": 1,
  "b": 4,
  "c": 0,
  "d": 2
}
{
  "b": 4,
  "d": 2,
  "a": 1,
  "c": 0
}

La mise en oeuvre

const _ = require('lodash');

const o = { a: 1, b: 4, c: 0, d: 2 };


function sortByValue(object, descending = true) {
  const { max, min } = Math;
  const selector = descending ? max : min;

  const objects = [];
  const cloned = _.clone(object);

  while (!_.isEmpty(cloned)) {
    const selectedValue = selector(...Object.values(cloned));
    const [key, value] = Object.entries(cloned).find(([, value]) => value === selectedValue);

    objects.push({ [key]: value });
    delete cloned[key];
  }

  return _.merge(...objects);
}

const o2 = sortByValue(o);
console.log(JSON.stringify(o2, null, 2));
James T.
la source
1
const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]

const order = ['test2', 'test']

const setOrder = (arrayOfObjects, order) =>
    arrayOfObjects.sort((a, b) => {
        if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
            return -1;
        }

        if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
            return 1;
        }

        return 0;
    });
Oleg
la source
1

ma solution avec tri:

let list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
};

let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);

for(let element of sorted) {
    console.log(element[0]+ ": " + element[1]);
}
Ivan Bozveliev
la source
Veuillez formater votre code en tant que code
Itamar Mushkin
1
<pre>
function sortObjectByVal(obj){  
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
    newObj[x] = obj[x];
}
return newObj;

}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>
Chirag Modi
la source
1
Bienvenue sur stackoverflow. En plus de la réponse que vous avez fournie, veuillez envisager de fournir une brève explication de la raison et de la manière dont cela résout le problème.
jtate
0

Une autre façon de résoudre ce problème: -

var res = [{"s1":5},{"s2":3},{"s3":8}].sort(function(obj1,obj2){ 
 var prop1;
 var prop2;
 for(prop in obj1) {
  prop1=prop;
 }
 for(prop in obj2) {
  prop2=prop;
 }
 //the above two for loops will iterate only once because we use it to find the key
 return obj1[prop1]-obj2[prop2];
});

// res aura le tableau de résultats

vivek_nk
la source
0

Merci et continuez de répondre @Nosredna

Maintenant que nous comprenons que l'objet doit être converti en tableau, puis triez le tableau. ceci est utile pour trier un tableau (ou un objet converti en tableau) par chaîne:

Object {6: Object, 7: Object, 8: Object, 9: Object, 10: Object, 11: Object, 12: Object}
   6: Object
   id: "6"
   name: "PhD"
   obe_service_type_id: "2"
   __proto__: Object
   7: Object
   id: "7"
   name: "BVC (BPTC)"
   obe_service_type_id: "2"
   __proto__: Object


    //Sort options
    var sortable = [];
    for (var vehicle in options)
    sortable.push([vehicle, options[vehicle]]);
    sortable.sort(function(a, b) {
        return a[1].name < b[1].name ? -1 : 1;
    });


    //sortable => prints  
[Array[2], Array[2], Array[2], Array[2], Array[2], Array[2], Array[2]]
    0: Array[2]
    0: "11"
    1: Object
        id: "11"
        name: "AS/A2"
        obe_service_type_id: "2"
        __proto__: Object
        length: 2
        __proto__: Array[0]
    1: Array[2]
    0: "7"
    1: Object
        id: "7"
        name: "BVC (BPTC)"
        obe_service_type_id: "2"
        __proto__: Object
        length: 2
Fureur
la source
0

Essaye ça. Même votre objet n'ayant pas la propriété sur laquelle vous essayez de trier sera également géré.

Appelez-le simplement en envoyant une propriété avec un objet.

var sortObjectByProperty = function(property,object){

    console.time("Sorting");
    var  sortedList      = [];
         emptyProperty   = [];
         tempObject      = [];
         nullProperty    = [];
    $.each(object,function(index,entry){
        if(entry.hasOwnProperty(property)){
            var propertyValue = entry[property];
            if(propertyValue!="" && propertyValue!=null){
              sortedList.push({key:propertyValue.toLowerCase().trim(),value:entry});  
            }else{
                emptyProperty.push(entry);
           }
        }else{
            nullProperty.push(entry);
        }
    });

      sortedList.sort(function(a,b){
           return a.key < b.key ? -1 : 1;
         //return a.key < b.key?-1:1;   // Asc 
         //return a.key < b.key?1:-1;  // Desc
      });


    $.each(sortedList,function(key,entry){
        tempObject[tempObject.length] = entry.value;
     });

    if(emptyProperty.length>0){
        tempObject.concat(emptyProperty);
    }
    if(nullProperty.length>0){
        tempObject.concat(nullProperty);
    }
    console.timeEnd("Sorting");
    return tempObject;
}
Vali Shah
la source