Objekteigenschaft nach Werten sortieren

696

Wenn ich ein JavaScript-Objekt habe wie:

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

Gibt es eine Möglichkeit, die Eigenschaften nach Wert zu sortieren? Damit ich am Ende mit

list = {
  "bar": 15, 
  "me": 75, 
  "you": 100, 
  "foo": 116
};
Steerpike
quelle
4
Nicht nur "sortieren", sondern vor allem Zahlen sortieren. Zahlen sind immun gegen die Javascripts Array.sort () -Methode, dh Sie müssen nicht nur eine Methode zum Sortieren von Eigenschaften finden, sondern auch Ihre eigene Funktion schreiben, um die numerischen Werte zu vergleichen.
Sampson
106
Bevor Sie die Antworten lesen: Die Antwort lautet Nein . Die Reihenfolge der Objekteigenschaften ist in ECMAScript nicht Standard. Sie sollten niemals Annahmen über die Reihenfolge der Elemente in einem JavaScript-Objekt treffen. Ein Objekt ist eine ungeordnete Sammlung von Eigenschaften. Die folgenden Antworten zeigen Ihnen, wie Sie sortierte Eigenschaften mithilfe von Arrays "verwenden", aber niemals die Reihenfolge der Eigenschaften von Objekten selbst ändern. Also, nein, das ist nicht möglich. Selbst wenn Sie ein Objekt mit vorsortierten Eigenschaften erstellen, kann nicht garantiert werden, dass diese in Zukunft in derselben Reihenfolge angezeigt werden. Weiter lesen :).
Govind Rai
3
@GovindRai In realen Frontend-Anwendungen durchlaufen wir Objektsammlungen mit IDs als Schlüssel, und die Reihenfolge ist wichtig, wenn sie in HTML-Vorlagen übersetzt werden. Sie sagen, sie haben keine Reihenfolge, ich sage, sie haben genau die Reihenfolge, die ich sehe, wenn console.logging sie im aktuellen Browser. Und diese Bestellung kann nachbestellt werden. Sobald Sie sie durchlaufen, haben sie eine Bestellung.
ProblemsOfSumit
7
@GovindRai: Es gibt jetzt eine Möglichkeit, auf Eigenschaften in einer bestimmten Reihenfolge in der Spezifikation zuzugreifen. Ist es eine gute Idee? Mit ziemlicher Sicherheit nicht. :-) Aber es ist da, ab ES2015.
TJ Crowder
7
Besucher 2019: Überprüfen Sie diese kaum positiv bewertete Object.entriesAntwort, die der sauberste und am besten lesbare Stand der Technik seit ES2017 ist: stackoverflow.com/a/37607084/245966
jakub.g

Antworten:

705

Verschieben Sie sie in ein Array, sortieren Sie das Array und verwenden Sie es dann für Ihre Zwecke. Hier ist eine Lösung:

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]]

Sobald Sie das Array haben, können Sie das Objekt aus dem Array in der gewünschten Reihenfolge neu erstellen und so genau das erreichen, was Sie sich vorgenommen haben. Das würde in allen mir bekannten Browsern funktionieren, aber es würde von einer Implementierungs-Eigenart abhängen und könnte jederzeit kaputt gehen. Sie sollten niemals Annahmen über die Reihenfolge der Elemente in einem JavaScript-Objekt treffen.

var objSorted = {}
sortable.forEach(function(item){
    objSorted[item[0]]=item[1]
})
Nosredna
quelle
24
Können Sie bitte "Sie können neu erstellen" in "Sie können das Array verwenden, um die Reihenfolge der Schlüssel beizubehalten und Werte aus dem Objekt abzurufen" umformulieren? Wie Sie selbst erwähnt haben, ist dies nicht nur kein Standard. Diese falsche Annahme wird heute von mehr Browsern als nur Chrome gebrochen. Es ist daher besser, die Benutzer nicht zu ermutigen, es zu versuchen.
Oleg V. Volkov
32
Hier ist eine kompaktere Version Ihres Codes. Object.keys (maxSpeed) .sort (Funktion (a, b) {return - (maxSpeed ​​[a] - maxSpeed ​​[b])});
TheBrain
6
@TheBrain: Nur zum Hinzufügen, keys()wird nur von IE9 + (und anderen modernen Browsern) unterstützt, wenn dies von Belang ist. keys()Schließt auch aufzählbare Eigenschaften aus der Prototypenkette der Elemente aus (im Gegensatz zu for..in) - aber das ist normalerweise wünschenswerter.
MrWhite
31
_.pairsverwandelt ein Objekt in [[Schlüssel1, Wert1], [Schlüssel2, Wert2]]. Rufen Sie dann sort an. Rufen Sie _.objectes dann an, um es zurückzudrehen.
Funkodebat
2
Mein Projekt erfordert Objektschlüssel zum sauberen Zusammenführen, erfordert jedoch auch eine explizite Sortierung, da die Benutzeroberfläche der Metadaten die Laufwerke steuert. Ich verfolgte einen ähnlichen Ansatz, nur fügte ich eine hasOwnProperty-Prüfung hinzu, um zu vermeiden, dass die Prototypenkette hochgekriecht wird. Hier ist ein guter Artikel über das Durchlaufen von Objekteigenschaften in JS hackernoon.com/…
Nathan Agersea
416

Wir möchten nicht die gesamte Datenstruktur duplizieren oder ein Array verwenden, für das wir ein assoziatives Array benötigen.

Hier ist eine andere Möglichkeit, dasselbe wie Bonna zu tun:

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.
quelle
22
Dies scheint eine Sortierung nach Schlüssel und nicht nach Wert zu sein. Was forderte die Frage nicht?
Michael
27
Es ist nach Wert sortiert und zeigt Schlüssel an - aber wir verlieren die Wertanzahl beim Ausdrucken, da nur Schlüssel gedruckt werden.
Hanna
6
Die Reihenfolge der Objekteigenschaften ist in JavaScript nicht garantiert. Daher sollte die Sortierung in ein Array und nicht in ein Objekt erfolgen (was Sie als "assoziatives Array" bezeichnen).
Christopher Meyers
6
Vergiss nicht. keysSortedist ein Array! Kein Objekt!
Grün
17
Wenn Sie .map(key => list[key]);am Ende der Sortierung hinzufügen , wird das gesamte Objekt anstelle nur des Schlüssels zurückgegeben
James Moran
182

Ihre Objekte können beliebig viele Eigenschaften haben, und Sie können wählen, ob Sie nach einer beliebigen Objekteigenschaft, einer beliebigen Nummer oder einer beliebigen Zeichenfolge sortieren möchten, wenn Sie die Objekte in ein Array einfügen. Betrachten Sie dieses Array:

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'
    }
];

sortieren nach Geburtsdatum, älteste zuerst

// 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);

Nach Name sortieren

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/

anorganik
quelle
1
Nach Namen sortieren sollte nicht substrdas erste Zeichen enthalten. sonst Dianaund Debrahaben eine undefinierte Reihenfolge. Außerdem verwendet Ihre byDateSorte tatsächlich numnicht born.
Lawrence Dol
Das sieht gut aus, aber beachten Sie, dass Sie zum Vergleichen von Zeichenfolgen einfach verwenden könnenx.localeCompare(y)
Jemar Jones
2
@JemarJones localComparesieht nach einer sehr nützlichen Funktion aus! Beachten Sie nur, dass es nicht in jedem Browser unterstützt wird - IE 10 und weniger, Safari Mobile 9 und weniger.
anorganik
@inorganik Ja, sehr guter Hinweis für diejenigen, die diese Browser unterstützen müssen
Jemar Jones
1
Dies ist eine Reihe von Objekten, nach denen nicht das OP gefragt ist (ein Objekt mit mehreren Eigenschaften)
João Pimentel Ferreira
62

Der Vollständigkeit halber gibt diese Funktion ein sortiertes Array von Objekteigenschaften zurück:

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 mit dem obigen Code ist hier . Diese Lösung basiert auf diesem Artikel .

Die aktualisierte Geige zum Sortieren von Zeichenfolgen finden Sie hier. Sie können beide zusätzlichen .toLowerCase () -Konvertierungen für den Vergleich von Zeichenfolgen mit Groß- und Kleinschreibung entfernen.

Stano
quelle
1
Was ist mit einer Reihe von Objekten? [{Name: Will}, {Name: Bill}, {Name: Ben}]
Will Hancock
1
Hallo Will, Sie können die localeCompare-Funktion für diesen Vergleich verwenden. Fügte es der obigen Antwort hinzu.
Stano
Tolle Lösung. Die Zeichenfolgensortierung benötigt eine Rückgabe
pfwd
@Stano Richtige und einfache Lösung. Vielen Dank.
Abrar Hossain
48

ECMAScript 2017 wird vorgestellt Object.values / Object.entries. Wie der Name schon sagt, fasst der erstere alle Werte eines Objekts zu einem Array zusammen, und der letztere fasst das gesamte Objekt zu einem Array von [key, value]Arrays zusammen. Pythons Äquivalent zu dict.values()und dict.items().

Die Funktionen machen es ziemlich einfach, jeden Hash in ein geordnetes Objekt zu sortieren. Ab sofort unterstützt nur ein kleiner Teil der JavaScript - Plattformen sie , aber Sie können es auf Firefox 47+ versuchen.

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
quelle
Wie beantwortet dies möglicherweise den Titel der Frage Sorting JavaScript Object by property value? Sie haben die Frage, glaube ich, falsch verstanden, da Sie das ursprüngliche Objekt ändern und kein neues Array daraus erstellen sollen.
vsync
2
@vsync Diese Antwort liefert das gleiche Ergebnis wie die akzeptierte Antwort, jedoch mit weniger Code und ohne temporäre Variable.
Darren Cook
3
FWIW, diese Antwort ist sauber und die einzige, die mir geholfen hat.
NetOperator Wibby
nur in ff, nicht mehr, noch in chrom sortieren sie die objekte automatisch. wtf
fb
Beachten Sie nur, dass dadurch keine Schlüssel erhalten bleiben.
Vael Victus
40

Eine "Pfeil" -Version der Antwort von @marcusR als Referenz

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

UPDATE: April 2017 - Dies gibt ein myObjoben definiertes sortiertes Objekt zurück.

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

Probieren Sie es hier aus!

UPDATE: Oktober 2018 - Object.entries-Version

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

Probieren Sie es hier aus!

Jason J. Nathan
quelle
1
funktioniert nicht fürvar myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}};
Rohanil
5
Die Frage des OP enthält zusammen mit dieser Antwort keine verschachtelten Objekte. @Rohanil Vielleicht möchten Sie eine andere Frage stellen, anstatt abzustimmen. Ihr verschachteltes Objekt mit verschiedenen Typen benötigt offensichtlich mehr als diese Lösung bietet
Jason J. Nathan
Nur eine Anmerkung: Ihre Updates funktionieren nicht wirklich. Zumindest nicht überall und nicht wegen entries. Nach dem Standard ist ein Objekt eine ungeordnete Sammlung von Eigenschaften . Das heißt, wenn Sie versuchen, das neue Objekt nach dem Sortieren nach Eigenschaftswert oder etwas anderem zu erstellen, wird die Reihenfolge der Eigenschaftsschlüssel wieder undefiniert. Chrome zum Beispiel bestellt standardmäßig die Eigenschaftsschlüssel, daher ist jeder Versuch, sie anders zu bestellen, nutzlos. Ihre einzige Chance besteht darin, einen "Index" basierend auf Ihren Bestelleinstellungen zu erhalten und das ursprüngliche Objekt entsprechend zu durchlaufen.
ZorgoZ
Ja @ZorgoZ, Sie haben Recht und viele Leute haben es in diesem Beitrag erwähnt. Meistens verwenden wir diese Funktion als Transformation, bevor wir sie in einen anderen Typ (wie JSON) oder vor einer anderen Reduktionsfunktion konvertieren. Wenn das Ziel darin besteht, das Objekt danach zu mutieren, kann es zu unerwarteten Ergebnissen kommen. Ich hatte Erfolg mit dieser Funktion über Motoren hinweg.
Jason J. Nathan
Hinweis: Sie möchten nicht verwenden sort()aufObject.entries()
Solvitieg
36

JavaScript-Objekte sind per Definition ungeordnet (siehe ECMAScript-Sprachspezifikation , Abschnitt 8.6). Die Sprachspezifikation garantiert nicht einmal, dass beim zweimaligen Durchlaufen der Eigenschaften eines Objekts diese beim zweiten Mal in derselben Reihenfolge angezeigt werden.

Wenn Sie Dinge bestellen möchten, verwenden Sie ein Array und die Methode Array.prototype.sort.

NickFitz
quelle
4
Beachten Sie, dass darüber ziemlich viel gestritten wurde. Die meisten Implementierungen behalten die Liste in der Reihenfolge bei, in der Elemente hinzugefügt wurden. IIRC, Chrome nicht. Es gab Streit darüber, ob Chrome mit den anderen Implementierungen übereinstimmen sollte. Ich glaube, dass ein JavaScript-Objekt ein Hash ist und keine Reihenfolge angenommen werden sollte. Ich glaube, Python hat das gleiche Argument durchlaufen und kürzlich wurde eine neue geordnete Hash-ähnliche Liste eingeführt. Bei den meisten Browsern können Sie tun, was Sie möchten, indem Sie Ihr Objekt neu erstellen und Elemente nach sortiertem Wert hinzufügen. Aber du solltest nicht.
Nosredna
Bearbeiten. Chrome hält normalerweise Ordnung, aber nicht immer. Und hier ist der relevante Chromium-Fehler: code.google.com/p/chromium/issues/detail?id=883
Nosredna
6
Dieser Fehlerbericht ist nicht gerechtfertigt, und diejenigen, die sich auf das undokumentierte Verhalten verlassen haben, sind diejenigen mit den Fehlern. Lesen Sie ECMASCript Abschnitt 8.6; Darin heißt es eindeutig: "Ein Objekt ist eine ungeordnete Sammlung von Eigenschaften". Jeder, der feststellte, dass dies in einigen Implementierungen nicht so schien, und dann begann, sich auf dieses implementierungsspezifische Verhalten zu verlassen, machte einen großen Fehler und sollte nicht versuchen, die Schuld von sich weg zu verlagern. Wenn ich im Chrome-Team wäre, würde ich diesen Fehlerbericht als "Ungültig, WontFix" markieren.
NickFitz
8
EcmaScript 5 definiert die Reihenfolge der Aufzählung tatsächlich als die Reihenfolge der Einfügung - das Fehlen einer Definition wird in ES3 als Spezifikationsfehler angesehen. Es ist erwähnenswert, dass die EcmaScript-Spezifikation ein Verhalten definiert, das niemand für vernünftig halten würde. Zum Beispiel ist das Spezifikationsverhalten, dass Syntaxfehler in vielen Fällen zur Laufzeit ausgelöst werden und die Verwendung von continue, break, ++, -, const usw. falsch erfolgt
Nach
4
@olliej - Ich denke nicht, dass das richtig ist. In der Spezifikation heißt es: "Die Mechanik und Reihenfolge der Aufzählung der Eigenschaften (Schritt 6.a im ersten Algorithmus, Schritt 7.a im zweiten) ist nicht angegeben." Dies ist auf Seite 92 des PDF des endgültigen Entwurfs.
Whitneyland
25

OK , wie Sie vielleicht wissen, hat Javascript die Funktion sort () , um Arrays zu sortieren, aber nichts für Objekte ...

In diesem Fall müssen wir also irgendwie ein Array der Schlüssel abrufen und sie sortieren. Dies ist der Grund, warum das Apis Ihnen die meiste Zeit Objekte in einem Array zur Verfügung stellt, da Array ohnehin mehr native Funktionen zum Spielen hat als Objektliteral. Die schnelle Lösung verwendet Object.key, das ein Array der Objektschlüssel zurückgibt. Ich erstelle die ES6- Funktion, die die Arbeit für Sie erledigt. Sie verwendet native Funktionen sort () und redu () in Javascript:

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

Und jetzt können Sie es so verwenden:

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

Überprüfen Sie das sortierte MyObject und Sie können das Ergebnis nach Schlüsseln wie folgt sortiert sehen:

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

Auch auf diese Weise wird das Hauptobjekt nicht berührt und wir erhalten tatsächlich ein neues Objekt.

Ich erstelle auch das Bild unten, um die Funktionsschritte klarer zu machen, falls Sie es ein wenig ändern müssen, um es auf Ihre Weise zu bearbeiten:

Sortieren eines Javascript-Objekts nach Eigenschaftswert

Alireza
quelle
4
Diese Sortierung nach Schlüssel, nicht nach Wert.
ROROROOROROR
@ROROROOROROR, es ist nur ein Hinweis darauf, wie es funktioniert, da sie nicht so unterschiedlich sind, aber alles gut, ich werde auch die Sortierung nach Wert hinzufügen
Alireza
1
Das Sortieren nach Wert ist falsch und es ist Ihr Datensatz. Wechseln Sie c: 3zu c: 13und Sie werden sehen, wie es auseinander fällt.
VtoCorleone
1
@VtoCorleone Das ist nur ein natürlicher Sortierfehler, 1 steht an erster Stelle, kein Fehler im dargestellten Algorithmus.
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
quelle
Einfach und perfekt! Dies beantwortet die Frage. Vielen Dank.
Ajay Singh
Die Schlüsselreihenfolge ist in Javascript nicht garantiert, daher schlägt dies für mich fehl, wenn Schlüssel Ganzzahlen oder ähnliches sind
ParoX
genau, ParoX. Dies funktioniert nicht richtig, wenn der Schlüssel vom Typ Integer ist.
Jungwon Jin
8

Update mit ES6: Wenn Ihr Anliegen ein sortiertes Objekt zum Durchlaufen hat (weshalb ich mir vorstellen würde, dass Sie Ihre Objekteigenschaften sortieren möchten), können Sie das Map- Objekt verwenden.

Sie können Ihre (Schlüssel-, Wert-) Paare in sortierter Reihenfolge einfügen. Wenn Sie dann eine for..ofSchleife ausführen, wird sichergestellt, dass sie in der Reihenfolge wiederholt werden, in der Sie sie eingefügt haben

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
quelle
Auch in ES6 (ES2015): Objekteigenschaften haben , um (oder es ist ein Mittel , sie in einer definierten Reihenfolge zugreifen, je nach Sichtweise ). Wenn die Eigenschaftsnamen Zeichenfolgen sind und nicht wie Array-Indizes aussehen, ist die Reihenfolge die Reihenfolge, in der sie dem Objekt hinzugefügt wurden. Diese Reihenfolge wird nicht angegeben, um von for-inoder eingehalten zu werden Object.keys, aber sie wird definiert, um von Object.getOwnPropertyNamesund den anderen neuen Methoden für den Zugriff auf Eigenschaftsnamen-Arrays eingehalten zu werden . Das ist also eine andere Option.
TJ Crowder
Aber wo ist die Sortieroperation? Sie sind überhaupt nicht sortiert
Green
@Green Ich denke, was ich hier hervorheben wollte, ist, dass MapSie tatsächlich eine Datenstruktur haben, die in sortierter Reihenfolge gespeichert werden kann (sortieren Sie Ihre Daten, durchlaufen Sie sie und speichern Sie sie in der Karte), wobei Ihnen dies nicht garantiert ist Objekte.
Julianljk
6

Underscore.js oder Lodash.js für erweiterte Array- oder Objektsortierungen

 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);

Demo

Roman Yudin
quelle
6

Sehr kurz und einfach!

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

Ich folge der Lösung von slebetman (lesen Sie sie für alle Details), aber angepasst, da Ihr Objekt nicht verschachtelt ist.

// 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
}
Bonna
quelle
4

Sortieren Sie Werte ohne mehrere for-Schleifen (um nach den Schlüsseln zu sortieren, ändern Sie den Index im Sortierrückruf auf "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
quelle
2

Dies könnte eine einfache Möglichkeit sein, es als real geordnetes Objekt zu behandeln. Ich bin mir nicht sicher, wie langsam es ist. könnte auch besser mit einer while-Schleife sein.

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

}

Und dann fand ich diese Invertierungsfunktion von: 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;
};

Damit

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
quelle
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
   } , [])

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

Kiran Debnath
quelle
2

Nur für den Fall, dass jemand versucht, das Objekt (mit Schlüsseln und Werten) unter Verwendung der Code-Referenz von @Markus R und @James Moran zu behalten, verwenden Sie einfach:

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
quelle
2
Sie geben eine Aufgabe zurück map, forEachwäre besser
DiegoRBaquero
2
let toSort = {a:2323, b: 14, c: 799} 
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1]) 

Ausgabe:

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

viele ähnliche und nützliche Funktionen: 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
quelle
1

Objekt sortiert nach Wert (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
quelle
1

Hier ist noch ein Beispiel:

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
quelle
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
quelle
1

Typoskript

Die folgende Funktion sortiert das Objekt nach Wert oder einer Eigenschaft des Werts. Wenn Sie TypeScript nicht verwenden, können Sie die Typinformationen entfernen, um sie in JavaScript zu konvertieren.

/**
 * 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);
}

Verwendungszweck

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);

Die Reihenfolge der Schlüssel in einem JavaScript-Objekt kann nicht garantiert werden. Daher sortiere ich das Ergebnis und gebe es als MapObjekt zurück, das die Sortierreihenfolge beibehält.

Wenn Sie es wieder in Object konvertieren möchten, können Sie dies tun:

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

Eingabe ist Objekt, Ausgabe ist Objekt, unter Verwendung der in lodash & js integrierten Bibliothek mit absteigender oder aufsteigender Option, und mutiert das Eingabeobjekt nicht

zB Eingabe & Ausgabe

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

Die Umsetzung

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.
quelle
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
quelle
1

meine Lösung mit sort:

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
quelle
Bitte formatieren Sie Ihren Code als 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
quelle
1
Willkommen beim Stackoverflow. Zusätzlich zu der Antwort, die Sie gegeben haben, sollten Sie eine kurze Erklärung darüber geben, warum und wie dies das Problem behebt.
13.
0

Ein anderer Weg, um dies zu lösen: -

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 hat das Ergebnisarray

vivek_nk
quelle
0

Vielen Dank und weiterhin antworten @Nosredna

Nachdem wir verstanden haben, dass das Objekt in ein Array konvertiert werden muss, sortieren Sie das Array. Dies ist nützlich, um das Array (oder das konvertierte Objekt in Array) nach Zeichenfolge zu sortieren:

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
Wut
quelle
0

Versuche dies. Selbst wenn Ihr Objekt nicht über die Eigenschaft verfügt, nach der Sie sortieren möchten, wird dies ebenfalls behandelt.

Rufen Sie es einfach auf, indem Sie eine Eigenschaft mit einem Objekt senden.

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
quelle