通过其值也是对象的键对对象进行排序,并对该内部对象进行排序,即递归地对对象进行排序。排序应该按键。
我查看了Stackoverflow的其他问题,但无是对象递归排序。
问题我调查了:
Sorting JavaScript Object by property value
示例:
input = {
"Memo": {
"itemAmount1": "5",
"taxName1": "TAX",
"productPrice1": "10",
"accountName1": "Account Receivable (Debtors)"
},
"Footer": {
"productDescription2": "Maggie",
"itemQuantity2": "49.5",
"accountName2": "Account Receivable (Debtors)",
"taxName2": "TAX"
},
"Header": {
"itemDiscount3": "10",
"accountName3": "Account Receivable (Debtors)",
"productPrice3": "10",
"taxName3": "TAX"
}
}
输出
output = {
"Footer": {
"accountName2": "Account Receivable (Debtors)",
"itemQuantity2": "49.5",
"productDescription2": "Maggie",
"taxName2": "TAX"
},
"Header": {
"accountName3": "Account Receivable (Debtors)",
"itemDiscount3": "10",
"productPrice3": "10",
"taxName3": "TAX"
},
"Memo": {
"accountName1": "Account Receivable (Debtors)",
"itemAmount1": "5",
"productPrice1": "10",
"taxName1": "TAX"
}
}
2级对象层次没有必要包含需要排序的 n级对象层次。
答案 0 :(得分:2)
我认为@ ksr89的意思是当我们应用for-in循环时,我们按排序顺序获取密钥。我认为这是一个有效的用例,特别是在基于Node.js的ORMs
的开发中以下功能应该有效,我认为你在寻找什么。
input = {
"Memo": {
"itemAmount1": "5",
"taxName1": "TAX",
"productPrice1": "10",
"accountName1": "Account Receivable (Debtors)"
},
"Footer": {
"productDescription2": "Maggie",
"itemQuantity2": "49.5",
"accountName2": "Account Receivable (Debtors)",
"taxName2": "TAX"
},
"Header": {
"itemDiscount3": "10",
"accountName3": "Account Receivable (Debtors)",
"productPrice3": "10",
"taxName3": "TAX"
}
}
window.sortedObject = sort(input);
function sort(object){
if (typeof object != "object" || object instanceof Array) // Not to sort the array
return object;
var keys = Object.keys(object);
keys.sort();
var newObject = {};
for (var i = 0; i < keys.length; i++){
newObject[keys[i]] = sort(object[keys[i]])
}
return newObject;
}
for (var key in sortedObject){
console.log (key);
//Prints keys in order
}
答案 1 :(得分:1)
上述解决方案仅适用于 node.js 的当前实现细节。
keys
次迭代的ECMAScript standard doesn't guarantee any order。
说我能想到的唯一解决方案是使用数组作为支持来对对象的properties
进行排序并迭代它:
var keys = Object.keys(object);
keys.sort();
for (var i = 0; i < keys.length; i++){
// this won't break if someone change NodeJS or Chrome implementation
console.log(keys[i]);
}
答案 2 :(得分:0)
我在此页面上写下以下信息。该代码基于Gaurav Ramanan的回答,但处理数组和null的方式不同。
要比较JSON文件中的数据,您可能希望采用相同的格式
JSON.stringify(JSON.parse(jsonString), null, '\t')
最后一个参数也可以是多个空格
最后两个参数是可选的(如果不存在,则会减少输出)验证缩进(TAB)和行尾(例如Unix)。 另外,在格式化过程中可能会对键进行递归排序。
使用javascript排序键:
const {isArray} = Array
const {keys} = Object
function sortKeysRec(obj) {
if (isArray(obj)) {
const newArray = []
for (let i = 0, l = obj.length; i < l; i++)
newArray[i] = sortKeysRec(obj[i])
return newArray
}
if (typeof obj !== 'object' || obj === null)
return obj
const sortedKeys = keys(obj).sort()
const newObject = {}
for (let i = 0, l = sortedKeys.length; i < l; i++)
newObject[sortedKeys[i]] = sortKeysRec(obj[sortedKeys[i]])
return newObject
}
确保使用javascript的unix行结尾:jsonString.replace(/\r\n/ug, '\n')
。
答案 3 :(得分:0)
由于这最近已经恢复,我认为值得再次指出,我们通常应该将对象视为属性的无序集合。尽管ES6确实指定了键遍历的顺序(通常是第一个添加到最后一个添加的属性,但对于类似于整数的键却有所不同),但是这取决于您是否在滥用类型。如果已订购,请使用数组。
也就是说,如果您确定要这样做,那么使用ES6就相对简单了:
const sortKeys = (o) =>
Object (o) !== o || Array .isArray (o)
? o
: Object .keys (o) .sort () .reduce ((a, k) => ({...a, [k]: sortKeys (o [k])}), {})
const input = {Memo: {itemAmount1: "5", taxName1: "TAX", productPrice1: "10", accountName1: "Account Receivable (Debtors)"}, Footer: {productDescription2: "Maggie", itemQuantity2: "49.5", accountName2: "Account Receivable (Debtors)", taxName2: "TAX"}, Header: {itemDiscount3: "10", accountName3: "Account Receivable (Debtors)", productPrice3: "10", taxName3: "TAX"}}
console .log (
sortKeys(input)
)
.as-console-wrapper {min-height: 100% !important; top: 0}
请注意,Rich Snapp很好地描述了此处存在潜在的性能问题。如果事实证明它是我的应用程序中的瓶颈,我只会花时间修复它,但是如果需要,我们可以使用以下类似版本来解决该问题:
const sortKeys = (o) =>
Object (o) !== o || Array .isArray (o)
? o
: Object .keys (o) .sort () .reduce ((a, k) => ((a [k] = sortKeys (o [k]), a)), {})
虽然这可行,但是添加逗号运算符和使用属性赋值使我感到不舒服。但是任何一个都应该起作用。