Skip to content Skip to sidebar Skip to footer

Sorting JavaScript Object By Key Value Recursively

Sort the objects by keys whose value is also an object and sort that internal object as well i.e sort the object recursively. Sorting should be as per key. I looked into Stackoverf

Solution 1:

I think what @ksr89 means is that when we apply a for - in loop, we get keys in sorted order. I think this is a valid use case especially in the development of Node.js based ORMs

The following function should work and is I think what you are looking for.

 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
}

Solution 2:

I was on this page to write the following information. The code is based on Gaurav Ramanan's answer, but handles arrays and null differently.

Comparing JSON

To compare data from JSON files you may want to have them formatted the same way

  • from javascript: JSON.stringify(JSON.parse(jsonString), null, '\t') the last parameter could also be a number of spaces the last 2 parameters are optional (minified output if absent)
  • from Visual Studio Code: with the Prettify JSON extension

Verify indentation (i.e. TABs) and line endings (i.e. Unix). Also, keys may be recursively sorted during formatting.

Sorting keys with 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
}

Ensure unix line endings with javascript: jsonString.replace(/\r\n/ug, '\n').


Solution 3:

The solution above works only for the current implementation detail of node.js.

The ECMAScript standard doesn't guarantee any order for the keys iteration.

That said, the only solution I can think of is to use an array as support to sort the properties of the object and iterate on it:

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]);
}

Solution 4:

As this has recently been revived, I think it's worth pointing out again that we should generally treat objects as unordered collections of properties. Although ES6 did specify key traversal order (mostly first-added to last-added properties, but with a twist for integer-like keys), depending on this feels as though you're misusing your type. If it's ordered, use an array.

That said, if you are determined to do this, then it's relatively simple with 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}

Note that there is a potential performance issue here as described well by Rich Snapp. I would only spend time fixing it if it turned out to be a bottleneck in my application, but if we needed to we could fix that issue with a version more like this:

const sortKeys = (o) =>
  Object (o) !== o || Array .isArray (o)
    ? o
    : Object .keys (o) .sort () .reduce ((a, k) => ((a [k] = sortKeys (o [k]), a)), {})

While this works, the addition of the comma operator and the use of property assignment make it uglier to my mind. But either one should work.


Solution 5:

Following up on @Gaurav Ramanan 's answer here's a shorter ES6 approach:

function sort(obj) {
  if (typeof obj !== "object" || Array.isArray(obj))
    return obj;
  const sortedObject = {};
  const keys = Object.keys(obj).sort();
  keys.forEach(key => sortedObject[key] = sort(obj[key]));
  return sortedObject;
}

This will leave intact values that are not objects and return a recursively sorted object.


Post a Comment for "Sorting JavaScript Object By Key Value Recursively"