按键值对JavaScript对象进行递归排序

时间:2014-07-08 10:51:29

标签: javascript node.js sorting recursion

通过其值也是对象的键对对象进行排序,并对该内部对象进行排序,即递归地对对象进行排序。排序应该按键。

我查看了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级对象层次

4 个答案:

答案 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文件中的数据,您可能希望采用相同的格式

  • 来自javascript:JSON.stringify(JSON.parse(jsonString), null, '\t') 最后一个参数也可以是多个空格 最后两个参数是可选的(如果不存在,则会减少输出)
  • 来自Visual Studio代码:具有Prettify JSON扩展名

验证缩进(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)), {})

虽然这可行,但是添加逗号运算符和使用属性赋值使我感到不舒服。但是任何一个都应该起作用。