Reputation: 2741
In order to better understand how to manipulate objects, I'm trying to sort an object based on its values.
eg.
let obj = {
1: 5,
2: 4,
3: 200,
4: 3,
5: 1
}
and I want an output of
{
3: 200,
1: 5,
2: 4,
4: 3,
5: 1
}
I've looped through the object and added its key value pairs into a new array, which I then sort by the values.
the new array looks like this
[
[3, 200],
[1, 5],
[2, 4],
[4, 3],
[5, 1]
]
I then loop through this array and create a new object from it, but it's coming out as
{ 1: 5, 2: 4, 3: 200, 4: 3, 5: 1 }
why?
let obj = {
1: 5,
2: 4,
3: 200,
4: 3,
5: 1
}
const sortObj = o => {
const arr = [];
const _obj = {};
for (const v in o) arr.push([v, o[v]]);
arr.sort((a, b) => b[1] - a[1]);
for (const v of arr) {
console.log(v);
/*
[
[3, 200],
[1, 5],
[2, 4],
[4, 3],
[5, 1]
]
*/
const [key, val] = v;
console.log(key, val);
_obj[key] = val;
}
return _obj;
}
console.log(sortObj(obj));
Upvotes: 0
Views: 54
Reputation: 5472
Use Map
if you can, it'll preserve order as mentioned in my comment above. The bonus of using Map
, your keys won't get converted to strings, it preserves the type too.
let obj = {
1: 5,
2: 4,
3: 200,
4: 3,
5: 1
}
const sortObj = o => {
const arr = [];
const map = new Map();
for (const v in o) arr.push([v, o[v]]);
arr.sort((a, b) => b[1] - a[1]);
for (const v of arr) {
console.log(v);
/*
[
[3, 200],
[1, 5],
[2, 4],
[4, 3],
[5, 1]
]
*/
const [key, val] = v;
//console.log(key, val);
map.set(key,val);
}
return map;
}
sortObj(obj).forEach((k,v)=>console.log(v,k))
Upvotes: 0
Reputation: 21672
As of ES2015, your objects keys will almost always preserve their order of insertion. However, one of the few notable exceptions is when your keys are integers.
The example below shows that the sort works fine when we use string
keys instead...
let obj = {
test: 5,
this: 4,
out: 200,
and: 3,
see: 1
}
const sortObj = o => {
const arr = [];
const _obj = {};
for (const v in o) arr.push([v, o[v]]);
arr.sort((a, b) => b[1] - a[1]);
for (const v of arr) {
const [key, val] = v;
_obj[key] = val;
}
return _obj;
}
console.log(sortObj(obj));
Alternatively, use a Map
instead, which always preserves order.
let obj = {
1: 5,
2: 4,
3: 200,
4: 3,
5: 1
}
const sortObj = o => {
const arr = [];
const _obj = new Map();
for (const v in o) arr.push([v, o[v]]);
arr.sort((a, b) => b[1] - a[1]);
for (const v of arr) {
const [key, val] = v;
_obj.set(key, val);
}
return _obj;
}
var sortedMap = sortObj(obj);
sortedMap.forEach((val, key) => console.log(`${key}: ${val}`));
Upvotes: 1
Reputation: 3753
Well, there is already a valid answer above but ill post it since i already started to play around with the ordering and have a bit shorter version.
Related reading: Does JavaScript Guarantee Object Property Order?
let obj = {
1: 5,
2: 4,
3: 200,
4: 3,
5: 1
}
sortedObj = Object.keys(obj).sort((key1, key2) => {
if (obj[key1] > obj[key2]) {return -1;}
if (obj[key1] < obj[key2]) {return 1;}
return 0;
}).reduce((acc, key) => {
acc['i_'+key] = obj[key];
return acc;
}, {});
Upvotes: 1