Sort Object Properties and JSON.Stringify

sort object properties and JSON.stringify

The simpler, modern and currently browser supported approach is simply this:

JSON.stringify(sortMyObj, Object.keys(sortMyObj).sort());

However, this method does remove any nested objects that aren't referenced and does not apply to objects within arrays. You will want to flatten the sorting object as well if you want something like this output:

{"a":{"h":4,"z":3},"b":2,"c":1}

You can do that with this:

var flattenObject = function(ob) {
var toReturn = {};

for (var i in ob) {
if (!ob.hasOwnProperty(i)) continue;

if ((typeof ob[i]) == 'object') {
var flatObject = flattenObject(ob[i]);
for (var x in flatObject) {
if (!flatObject.hasOwnProperty(x)) continue;

toReturn[i + '.' + x] = flatObject[x];
}
} else {
toReturn[i] = ob[i];
}
}
return toReturn;
};
var myFlattenedObj = flattenObject(sortMyObj);
JSON.stringify(myFlattenedObj, Object.keys(myFlattenedObj).sort());

To do it programmatically with something you can tweak yourself, you need to push the object property names into an array, then sort the array alphabetically and iterate through that array (which will be in the right order) and select each value from the object in that order. "hasOwnProperty" is checked also so you definitely have only the object's own properties. Here's an example:

var obj = {"a":1,"b":2,"c":3};

function iterateObjectAlphabetically(obj, callback) {
var arr = [],
i;

for (i in obj) {
if (obj.hasOwnProperty(i)) {
arr.push(i);
}
}

arr.sort();

for (i = 0; i < arr.length; i++) {
var key = obj[arr[i]];
//console.log( obj[arr[i]] ); //here is the sorted value
//do what you want with the object property
if (callback) {
// callback returns arguments for value, key and original object
callback(obj[arr[i]], arr[i], obj);
}
}
}

iterateObjectAlphabetically(obj, function(val, key, obj) {
//do something here
});

Again, this should guarantee that you iterate through in alphabetical order.

Finally, taking it further for the simplest way, this library will recursively allow you to sort any JSON you pass into it: https://www.npmjs.com/package/json-stable-stringify

var stringify = require('json-stable-stringify');
var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 };
console.log(stringify(obj));

Output

{"a":3,"b":[{"x":4,"y":5,"z":6},7],"c":8}

Does JSON.stringify preserves order of objects in array

There is nothing in the docs that explicitly confirms that the order of array items is preserved. However, the docs state that for non-array properties, order is not guaranteed:

Properties of non-array objects are not guaranteed to be stringified in any particular order. Do not rely on ordering of properties within the same object within the stringification.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

Even if the order of array items would be preserved, I would not count on this but rather sort the items myself. After all, there will most likely be some business or presentation logic that indicates how the items should be sorted.

How to reset object's property order? JSON.stringify() preserves them

No, there is not any way beyond putting the keys into an array. The reason is that JavaScript objects do not have any meaningful order to their keys.

JavaScript objects are essentially hash maps, meaning that there is constant lookup time given any key but the keys themselves do not have a meaningful order. Since the only reason to sort keys in JavaScript would be for readability purposes, there is not a built-in solution that handles this better.

Stringify an JS Object in Asc order

If the order is important for you, don't use JSON.stringify because the order is not safe using it, you can create your JSON stringify using javascript, to deal with string values we have 2 different ways, first to do it using regexp an replace invalid characters or using JSON.stringify for our values, for instance if we have a string like 'abc\d"efg', we can simply get the proper result JSON.stringify('abc\d"efg'), because the whole idea of this function is to stringify in a right order:

function sort_stringify(obj){
var sortedKeys = Object.keys(obj).sort();
var arr = [];
for(var i=0;i<sortedKeys.length;i++){
var key = sortedKeys[i];
var value = obj[key];
key = JSON.stringify(key);
value = JSON.stringify(value);
arr.push(key + ':' + value);
}
return "{" + arr.join(",\n\r") + "}";
}
var jsonString = sort_stringify(yourObj);

If we wanted to do this not using JSON.stringify to parse the keys and values, the solution would be like:

function sort_stringify(obj){
var sortedKeys = Object.keys(obj).sort();
var arr = [];
for(var i=0;i<sortedKeys.length;i++){
var key = sortedKeys[i];
var value = obj[key];
key = key.replace(/"/g, '\\"');
if(typeof value != "object")
value = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
arr.push('"' + key + '":"' + value + '"');
}
return "{" + arr.join(",\n\r") + "}";
}

sort json object in javascript

First off, that's not JSON. It's a JavaScript object literal. JSON is a string representation of data, that just so happens to very closely resemble JavaScript syntax.

Second, you have an object. They are unsorted. The order of the elements cannot be guaranteed. If you want guaranteed order, you need to use an array. This will require you to change your data structure.

One option might be to make your data look like this:

var json = [{
"name": "user1",
"id": 3
}, {
"name": "user2",
"id": 6
}, {
"name": "user3",
"id": 1
}];

Now you have an array of objects, and we can sort it.

json.sort(function(a, b){
return a.id - b.id;
});

The resulting array will look like:

[{
"name": "user3",
"id" : 1
}, {
"name": "user1",
"id" : 3
}, {
"name": "user2",
"id" : 6
}];

Sorting object property by values

Move them to an array, sort that array, and then use that array for your purposes. Here's a solution:

let maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
let sortable = [];
for (var vehicle in maxSpeed) {
sortable.push([vehicle, maxSpeed[vehicle]]);
}

sortable.sort(function(a, b) {
return a[1] - b[1];
});

// [["bike", 60], ["motorbike", 200], ["car", 300],
// ["helicopter", 400], ["airplane", 1000], ["rocket", 28800]]

Once you have the array, you could rebuild the object from the array in the order you like, thus achieving exactly what you set out to do. That would work in all the browsers I know of, but it would be dependent on an implementation quirk, and could break at any time. You should never make assumptions about the order of elements in a JavaScript object.

let objSorted = {}
sortable.forEach(function(item){
objSorted[item[0]]=item[1]
})

In ES8, you can use Object.entries() to convert the object into an array:

const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};

const sortable = Object.entries(maxSpeed)
.sort(([,a],[,b]) => a-b)
.reduce((r, [k, v]) => ({ ...r, [k]: v }), {});

console.log(sortable);

object not sort based on the value in JavaScript (having key and value number)

Although JavaScript object properties have an order now, relying on their order is an antipattern.

If you need order, use an array.

required output

You cannot get the required output with a JavaScript object, because:

  • Those property names are array index names, and so the object's "order" puts them in order numerically.
  • JSON.stringify follows the property order of the object.

Also note that JSON (as distinct from JavaScript) considers objects "...an unordered set of name/value pairs..." So to JSON, {"a": 1, "b": 2} and {"b": 2, "a": 1} are exactly equivalent.

You could use a Map, but then the JSON representation wouldn't be what you're expecting.

Or you could build the JSON manually (ignoring that JSON doesn't consider objets to have any order), using JSON.stringify for the values but outputting the {, property names, and } yourself.

But really, if you need order, use an array.

Here's an example using an array of arrays:

let team_id_Point = [
[26, 15],
[32, 1],
[127, 21],
];

function sortTeamIdPoint(data = [], asc = true) {
const result = [...data];
const sign = asc ? 1 : -1;
result.sort((a, b) => (a[0] - b[0]) * sign);
return JSON.stringify(result);
}

console.log(sortTeamIdPoint(team_id_Point, false));


Related Topics



Leave a reply



Submit