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
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:
- Lassen Schlüssel eine neue leere Liste sein.
- 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.
- 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.
- 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.
- 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 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;
}
.