何らかの理由で、ネストされたオブジェクトの場合、受け入れられた回答が機能しません。これにより、自分でコードを作成するようになりました。私がこれを書いているのは2019年後半なので、言語内で利用できるオプションがいくつかあります。
更新:デビッドファーロングの答えは以前の試みに対する望ましいアプローチであると私は信じています。MineはObject.entries(...)のサポートに依存しているため、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);
-
この古いバージョンを履歴参照のために保持する
オブジェクト内のすべてのキーのシンプルでフラットな配列が機能することがわかりました。ほとんどすべてのブラウザー(EdgeまたはInternet Explorerではなく、予想どおり)およびNode 12+では、Array.prototype.flatMap(...)が利用できるようになったため、かなり短い解決策があります。(lodashの同等物も機能します。)私はSafari、Chrome、Firefoxでのみテストしましたが、flatMapと標準のJSON.stringify(...)をサポートする他の場所で機能しない理由はわかりません。
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);
}
これにより、サードパーティの依存関係なしで文字列化でき、さらにキーと値のエントリのペアでソートする独自のソートアルゴリズムを渡すことができるため、キー、ペイロード、またはその2つの組み合わせでソートできます。ネストされたオブジェクト、配列、および単純な古いデータ型の混合で機能します。
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));
プリント:
{
"a": 2,
"b": 1,
"c": {
"x": 3,
"y": [
2048,
1999,
{
"f": 5,
"g": "help",
"x": false
}
],
"z": 4
}
}
古いJavaScriptエンジンとの互換性が必要な場合は、flatMapの動作をエミュレートするこれらの少し冗長なバージョンを使用できます。クライアントは少なくともES5をサポートする必要があるため、Internet Explorer 8以下はサポートされません。
これらは上記と同じ結果を返します。
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);
}