Schlüssel in Javascript-Objekt sortieren

Lesezeit: 5 Minuten

Ich habe ein Javascript-Objekt, das eine Mischung aus Eigenschaftstypen enthält, darunter einfache Zeichenfolgen, Objekte, Arrays von Objekten … und so weiter.

Ich möchte die Schlüssel nach dieser Regel sortieren:

‘Einfache Eigenschaften wie Strings oder Zahlen erscheinen immer vor komplexeren Eigenschaften, die Arrays oder Objekte enthalten.’

Ich habe die folgende Funktion geschrieben, die fast das tut, was ich erreichen möchte, aber sie wandelt die Arrays in Objekte um. Dies ist nicht das gewünschte Verhalten. Kann mir jemand helfen, eine Funktion zu erstellen, die Arrays als Arrays behält und gleichzeitig die Objekte innerhalb von Arrays sortiert?

function sort(object){
    if (typeof object != "object" )
        return object;
    var keys = Object.keys(object);
    keys.sort(function(a,b){
            if (typeof(object[a])!== 'object') { return -1 } else { return 1 }
        });

Funktionierende jsfiddle:

http://jsfiddle.net/u01mn2py/3/

Mit freundlichen Grüße

Schlussel in Javascript Objekt sortieren
TJ Crowder

Ab ECMAScript 2015 (ES6) kann ein Objekt eigen Eigenschaften tun habe ordnung für einige Operationen, obwohl es selten eine gute Idee ist, sich darauf zu verlassen. Wenn Sie Ordnung wünschen, ist es normalerweise am besten, ein Array oder ähnliches zu verwenden.

Die Reihenfolge lautet:

  1. Lassen Schlüssel eine neue leere Liste sein.
  2. Für jeden eigenen Eigenschaftsschlüssel P von Ö das ist ein ganzzahliger Index in aufsteigender numerischer Indexreihenfolge
    • Hinzufügen P als letztes Element von Schlüssel.
  3. Für jeden eigenen Eigenschaftsschlüssel P von Ö das ist ein String, aber kein ganzzahliger Index, in der Reihenfolge der Eigenschaftserstellung
    • Hinzufügen P als letztes Element von Schlüssel.
  4. Für jeden eigenen Eigenschaftsschlüssel P von Ö das ist ein Symbol in der Reihenfolge der Eigenschaftserstellung
    • Hinzufügen P als letztes Element von Schlüssel.
  5. Zurückkehren Schlüssel.

Das ist für “eigene” Eigenschaften. Ich glaube nicht, dass es extern verfügbare Operationen gibt, die eine erforderliche Reihenfolge für alle Eigenschaften einschließlich der geerbten definieren. (for-in ist nicht erforderlich, die obige Reihenfolge einzuhalten, auch nicht in ES2015+.) Ab ES2019, for-in hat eine definierte Reihenfolge (mit einigen Ausnahmen).

Dies bedeutet, dass es wahrscheinlich möglich ist, auf einer kompatiblen Engine das zu tun, was Sie gefragt haben, vorausgesetzt, keiner unserer Schlüssel ist als ganzzahliger Index qualifiziert.

JSON hat noch keine Reihenfolge, aber JSON.stringify wird von der JavaScript-Spezifikation benötigt, um die oben beschriebene Reihenfolge zu verwenden.

Ich sage nicht, dass ich empfehlen es. 🙂

function sort(object) {
    // Don't try to sort things that aren't objects
    if (typeof object != "object") {
        return object;
    }

    // Don't sort arrays, but do sort their contents
    if (Array.isArray(object)) {
        object.forEach(function(entry, index) {
            object[index] = sort(entry);
        });
        return object;
    }

    // Sort the keys
    var keys = Object.keys(object);
    keys.sort(function (a, b) {
        var atype = typeof object[a],
            btype = typeof object[b],
            rv;
        if (atype !== btype && (atype === "object" || btype === "object")) {
            // Non-objects before objects
            rv = atype === 'object' ? 1 : -1;
        } else {
            // Alphabetical within categories
            rv = a.localeCompare(b);
        }
        return rv;
    });

    // Create new object in the new order, sorting
    // its subordinate properties as necessary
    var newObject = {};
    keys.forEach(function(key) {
        newObject[key] = sort(object[key]);
    });
    return newObject;
}

Live-Beispiel (ich auch aktualisiert die Geige):

function sort(object) {
    // Don't try to sort things that aren't objects
    if (typeof object != "object") {
        return object;
    }
    
    // Don't sort arrays, but do sort their contents
    if (Array.isArray(object)) {
        object.forEach(function(entry, index) {
            object[index] = sort(entry);
        });
        return object;
    }
    
    // Sort the keys
    var keys = Object.keys(object);
    keys.sort(function (a, b) {
        var atype = typeof object[a],
            btype = typeof object[b],
            rv;
        if (atype !== btype && (atype === "object" || btype === "object")) {
            // Non-objects before objects
            rv = atype === 'object' ? 1 : -1;
        } else {
            // Alphabetical within categories
            rv = a.localeCompare(b);
        }
        return rv;
    });
    
    // Create new object in the new order, sorting
    // its subordinate properties as necessary
    var newObject = {};
    keys.forEach(function(key) {
        newObject[key] = sort(object[key]);
    });
    return newObject;
}

var object = {
    family: [{
        home: {
            city: 'Madrid'
        },
        birth: {
            city: 'Madrid'
        },
        name: 'John',
        age: 32

    }, {
        home: {
            city: 'London'
        },
        birth: {
            city: 'Paris'
        },
        name: 'Marie',
        age: 25
    }],
    name: 'Dani',
    age: 33
};
var sortedObject = sort(object);
document.getElementById('container').innerHTML = JSON.stringify(sortedObject, null, 't');
<pre id="container">
</pre>

(Sie haben nicht nach alphabetischen Kategorien innerhalb von Kategorien gefragt, aber es schien eine vernünftige Sache zu geben.)

Das funktioniert bei mir auf aktuellem Chrome, Firefox und IE11.

  • Ich muss das Objekt nur als geordnetes JSON anzeigen (gemäß meiner Regel), aber JSON.stringify hat keine Sortieroptionen. Wie kann ich das machen?

    – Wildbyte

    14. April ’15 um 9:14


  • @wildbyte: Richtig. Auch in JSON haben Eigenschaften keine Reihenfolge. Wenn Sie möchten, dass ein JSON-String die Eigenschaften in einer bestimmten Reihenfolge auflistet, müssen Sie dafür Ihre eigene Funktion erstellen. (Ich musste das vor einiger Zeit machen, kann diesen Code aber leider nicht teilen. Aber es ist nicht so schwer, du kannst ihn verwenden JSON.stringify für Teile davon, aber Sie müssen die Rekursion und Iteration definieren. Hat ungefähr 15 Codezeilen gebraucht.)

    – TJ Crowder

    14. Apr. ’15 um 9:15


  • @wildbyte: Ich habe die Antwort aktualisiert, nachdem ECMAScript 2015 fertiggestellt wurde.

    – TJ Crowder

    7. August ’15 um 6:45

Ich weiß, dass ich die Reihenfolge der Javascript-Eigenschaften nicht weitergeben kann, aber ich muss visuell sortiertes JSON anzeigen. So gelöst:

http://jsfiddle.net/u01mn2py/4/

function sort(object){
    if (typeof object != "object" ) // Not to sort the array
        return object;
    var keys = Object.keys(object);
    keys.sort(function(a,b){
            if (typeof(object[a])!== 'object') { return -1 } else { return 1 }
        });
    if( Object.prototype.toString.call( object ) === '[object Array]' ) {
        var newObject = [];
     } else {
        var newObject = {}; }

     for (var i = 0; i < keys.length; i++){
            newObject[keys[i]] = sort(object[keys[i]])
      }
    return newObject;
}

.

228890cookie-checkSchlüssel in Javascript-Objekt sortieren

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy