คำตอบที่ยอมรับใช้ไม่ได้สำหรับฉันสำหรับวัตถุที่ซ้อนกันด้วยเหตุผลบางประการ สิ่งนี้ทำให้ฉันต้องเขียนโค้ดของตัวเอง เนื่องจากเป็นช่วงปลายปี 2019 เมื่อฉันเขียนสิ่งนี้จึงมีตัวเลือกเพิ่มเติมอีกสองสามอย่างในภาษานี้
อัปเดต: ฉันเชื่อว่าคำตอบของ David Furlongเป็นแนวทางที่ดีกว่าสำหรับความพยายามก่อนหน้านี้ของฉันและฉันได้แยกแยะสิ่งนั้นออกไปแล้ว 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);
}
ด้วยวิธีนี้คุณสามารถสตริงโดยไม่มีการอ้างอิงของบุคคลที่สามและยังส่งผ่านอัลกอริทึมการจัดเรียงของคุณเองที่เรียงลำดับตามคู่รายการคีย์ - ค่าดังนั้นคุณจึงสามารถจัดเรียงตามคีย์เพย์โหลดหรือทั้งสองอย่างรวมกันได้ ใช้ได้กับอ็อบเจ็กต์อาร์เรย์ที่ซ้อนกันและส่วนผสมของชนิดข้อมูลเก่าล้วน
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 รุ่นเก่าคุณสามารถใช้เวอร์ชัน verbose เพิ่มเติมเล็กน้อยเหล่านี้เพื่อเลียนแบบพฤติกรรม 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);
}