La réponse acceptée ne fonctionne pas pour moi pour les objets imbriqués pour une raison quelconque. Cela m'a amené à coder le mien. Comme il est fin 2019 lorsque j'écris ceci, il y a quelques autres options disponibles dans la langue.
Mise à jour: Je pense que la réponse de David Furlong est une approche préférable à ma tentative précédente, et je l'ai écartée. Le mien repose sur le support d'Object.entries (...), donc pas de support d'Internet Explorer.
function normalize(sortingFunction) {
return function(key, value) {
if (typeof value === 'object' && !Array.isArray(value)) {
return Object
.entries(value)
.sort(sortingFunction || undefined)
.reduce((acc, entry) => {
acc[entry[0]] = entry[1];
return acc;
}, {});
}
return value;
}
}
JSON.stringify(obj, normalize(), 2);
-
CONSERVER CETTE ANCIENNE VERSION POUR RÉFÉRENCE HISTORIQUE
J'ai trouvé qu'un tableau simple et plat de toutes les clés de l'objet fonctionnera. Dans presque tous les navigateurs (pas Edge ou Internet Explorer, comme on pouvait s'y attendre ) et Node 12+, il existe une solution assez courte maintenant que Array.prototype.flatMap (...) est disponible. (L'équivalent lodash fonctionnerait aussi.) Je n'ai testé que dans Safari, Chrome et Firefox, mais je ne vois aucune raison pour laquelle cela ne fonctionnerait pas ailleurs qui prend en charge flatMap et JSON.stringify standard (...) .
function flattenEntries([key, value]) {
return (typeof value !== 'object')
? [ [ key, value ] ]
: [ [ key, value ], ...Object.entries(value).flatMap(flattenEntries) ];
}
function sortedStringify(obj, sorter, indent = 2) {
const allEntries = Object.entries(obj).flatMap(flattenEntries);
const sorted = allEntries.sort(sorter || undefined).map(entry => entry[0]);
return JSON.stringify(obj, sorted, indent);
}
Avec cela, vous pouvez stringify sans dépendances tierces et même passer votre propre algorithme de tri qui trie sur les paires d'entrées clé-valeur, de sorte que vous pouvez trier par clé, charge utile ou une combinaison des deux. Fonctionne pour les objets imbriqués, les tableaux et tout mélange d'anciens types de données.
const obj = {
"c": {
"z": 4,
"x": 3,
"y": [
2048,
1999,
{
"x": false,
"g": "help",
"f": 5
}
]
},
"a": 2,
"b": 1
};
console.log(sortedStringify(obj, null, 2));
Impressions:
{
"a": 2,
"b": 1,
"c": {
"x": 3,
"y": [
2048,
1999,
{
"f": 5,
"g": "help",
"x": false
}
],
"z": 4
}
}
Si vous devez être compatible avec les moteurs JavaScript plus anciens , vous pouvez utiliser ces versions légèrement plus détaillées qui émulent le comportement de flatMap. Le client doit prendre en charge au moins ES5, donc pas d'Internet Explorer 8 ou inférieur.
Ceux-ci renverront le même résultat que ci-dessus.
function flattenEntries([key, value]) {
if (typeof value !== 'object') {
return [ [ key, value ] ];
}
const nestedEntries = Object
.entries(value)
.map(flattenEntries)
.reduce((acc, arr) => acc.concat(arr), []);
nestedEntries.unshift([ key, value ]);
return nestedEntries;
}
function sortedStringify(obj, sorter, indent = 2) {
const sortedKeys = Object
.entries(obj)
.map(flattenEntries)
.reduce((acc, arr) => acc.concat(arr), [])
.sort(sorter || undefined)
.map(entry => entry[0]);
return JSON.stringify(obj, sortedKeys, indent);
}