Sorting JavaScript Object By Key Value Recursively
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"