Sorting collection of objects by value inside object [duplicate] - javascript

If I have a JavaScript object such as:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
Is there a way to sort the properties based on value? So that I end up with
list = {
"bar": 15,
"me": 75,
"you": 100,
"foo": 116
};

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);
In ES10, you can use Object.fromEntries() to convert array to object. Then the code can be simplified to this:
const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
const sortable = Object.fromEntries(
Object.entries(maxSpeed).sort(([,a],[,b]) => a-b)
);
console.log(sortable);

We don't want to duplicate the entire data structure, or use an array where we need an associative array.
Here's another way to do the same thing as bonna:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted); // bar,me,you,foo

Your objects can have any amount of properties and you can choose to sort by whatever object property you want, number or string, if you put the objects in an array. Consider this array:
var arrayOfObjects = [
{
name: 'Diana',
born: 1373925600000, // Mon, Jul 15 2013
num: 4,
sex: 'female'
},
{
name: 'Beyonce',
born: 1366832953000, // Wed, Apr 24 2013
num: 2,
sex: 'female'
},
{
name: 'Albert',
born: 1370288700000, // Mon, Jun 3 2013
num: 3,
sex: 'male'
},
{
name: 'Doris',
born: 1354412087000, // Sat, Dec 1 2012
num: 1,
sex: 'female'
}
];
sort by date born, oldest first
// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
return a.born - b.born;
});
console.log('by date:');
console.log(byDate);
sort by name
var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
return x < y ? -1 : x > y ? 1 : 0;
});
console.log('by name:');
console.log(byName);
http://jsfiddle.net/xsM5s/16/

ECMAScript 2017 introduces Object.values / Object.entries. As the name suggests, the former aggregates all the values of an object into an array, and the latter does the whole object into an array of [key, value] arrays; Python's equivalent of dict.values() and dict.items().
The features make it pretty easier to sort any hash into an ordered object. As of now, only a small portion of JavaScript platforms support them, but you can try it on Firefox 47+.
EDIT: Now supported by all modern browsers!
let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]
let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]

For completeness sake, this function returns sorted array of object properties:
function sortObject(obj) {
var arr = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) { return a.value - b.value; });
//arr.sort(function(a, b) { return a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
return arr; // returns array
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]
JSFiddle with the code above is here. This solution is based on this article.
Updated fiddle for sorting strings is here. You can remove both additional .toLowerCase() conversions from it for case sensitive string comparation.

An "arrowed" version of #marcusR 's answer for reference
var myObj = { you: 100, me: 75, foo: 116, bar: 15 };
keysSorted = Object.keys(myObj).sort((a, b) => myObj[a] - myObj[b]);
alert(keysSorted); // bar,me,you,foo
UPDATE: April 2017
This returns a sorted myObj object defined above.
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result =
Object.keys(myObj)
.sort((a, b) => myObj[a] - myObj[b])
.reduce(
(_sortedObj, key) => ({
..._sortedObj,
[key]: myObj[key]
}),
{}
);
document.write(JSON.stringify(result));
UPDATE: March 2021 - Object.entries with sort function (updated as per comments)
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result = Object
.entries(myObj)
.sort((a, b) => a[1] - b[1])
.reduce((_sortedObj, [k,v]) => ({
..._sortedObj,
[k]: v
}), {})
document.write(JSON.stringify(result));

JavaScript objects are unordered by definition (see the ECMAScript Language
Specification, section 8.6). The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you need things to be ordered, use an array and the Array.prototype.sort method.

OK, as you may know, javascript has sort() function, to sort arrays, but nothing for object...
So in that case, we need to somehow get array of the keys and sort them, thats the reason the apis gives you objects in an array most of the time, because Array has more native functions to play with them than object literal, anyway, the quick solotion is using Object.key which return an array of the object keys, I create the ES6 function below which does the job for you, it uses native sort() and reduce() functions in javascript:
function sortObject(obj) {
return Object.keys(obj)
.sort().reduce((a, v) => {
a[v] = obj[v];
return a; }, {});
}
And now you can use it like this:
let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);
Check the sortedMyObject and you can see the result sorted by keys like this:
{a: 1, b: 2, c: 3, d: 4, e: 5}
Also this way, the main object won't be touched and we actually getting a new object.
I also create the image below, to make the function steps more clear, in case you need to change it a bit to work it your way:

var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
function sortAssocObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
// [["you",100],["me",75],["foo",116],["bar",15]]
sortable.sort(function(a, b) {
return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
});
// [["bar",15],["me",75],["you",100],["foo",116]]
var orderedList = {};
for (var idx in sortable) {
orderedList[sortable[idx][0]] = sortable[idx][1];
}
return orderedList;
}
sortAssocObject(list);
// {bar: 15, me: 75, you: 100, foo: 116}

Update with ES6: If your concern is having a sorted object to iterate through (which is why i'd imagine you want your object properties sorted), you can use the Map object.
You can insert your (key, value) pairs in sorted order and then doing a for..of loop will guarantee having them loop in the order you inserted them
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
// 0 = zero
// 1 = one

Sort values without multiple for-loops (to sort by the keys change index in the sort callback to "0")
const list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.fromEntries(
Object.entries(list).sort( (a,b) => a[1] - b[1] )
)
console.log('Sorted object: ', sorted)

Very short and simple!
var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
sortedList[key] = list[key]; });

Underscore.js or Lodash.js for advanced array or object sorts
var data = {
"models": {
"LTI": [
"TX"
],
"Carado": [
"A",
"T",
"A(пасс)",
"A(груз)",
"T(пасс)",
"T(груз)",
"A",
"T"
],
"SPARK": [
"SP110C 2",
"sp150r 18"
],
"Autobianchi": [
"A112"
]
}
};
var arr = [],
obj = {};
for (var i in data.models) {
arr.push([i, _.sortBy(data.models[i], function(el) {
return el;
})]);
}
arr = _.sortBy(arr, function(el) {
return el[0];
});
_.map(arr, function(el) {
return obj[el[0]] = el[1];
});
console.log(obj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js" integrity="sha256-qXBd/EfAdjOA2FGrGAG+b3YBn2tn5A6bhz+LSgYD96k=" crossorigin="anonymous"></script>

I am following the solution given by slebetman (go read it for all the details), but adjusted, since your object is non-nested.
// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
sort_array.push({key:key,value:list[key]});
}
// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});
// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
var item = list[sort_array[i].key];
// now do stuff with each item
}

let toSort = {a:2323, b: 14, c: 799}
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1])
Output:
[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]

There are many ways to do this, but since I didn't see any using reduce() I put it here. Maybe it seems utils to someone.
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let result = Object.keys(list).sort((a,b)=>list[a]>list[b]?1:-1).reduce((a,b)=> {a[b]=list[b]; return a},{});
console.log(result);

Thanks to #orad for providing the answer in TypeScript. Now, We can use the below codesnippet in JavaScript.
function sort(obj,valSelector) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
const Countries = { "AD": { "name": "Andorra", }, "AE": { "name": "United Arab Emirates", }, "IN": { "name": "India", }}
// Sort the object inside object.
var sortedMap = sort(Countries, val => val.name);
// Convert to object.
var sortedObj = {};
sortedMap.forEach((v,k) => { sortedObj[k] = v }); console.log(sortedObj);
//Output: {"AD": {"name": "Andorra"},"IN": {"name": "India"},"AE": {"name": "United Arab Emirates"}}

Sorting object property by values
const obj = { you: 100, me: 75, foo: 116, bar: 15 };
const keysSorted = Object.keys(obj).sort((a, b) => obj[a] - obj[b]);
const result = {};
keysSorted.forEach(key => { result[key] = obj[key]; });
document.write('Result: ' + JSON.stringify(result));
The desired output:
{"bar":15,"me":75,"you":100,"foo":116}
References:
Sorting object property by values
Convert array into object

This could be a simple way to handle it as a real ordered object. Not sure how slow it is. also might be better with a while loop.
Object.sortByKeys = function(myObj){
var keys = Object.keys(myObj)
keys.sort()
var sortedObject = Object()
for(i in keys){
key = keys[i]
sortedObject[key]=myObj[key]
}
return sortedObject
}
And then I found this invert function from:
http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/
Object.invert = function (obj) {
var new_obj = {};
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
new_obj[obj[prop]] = prop;
}
}
return new_obj;
};
So
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)

Just in case, someone is looking for keeping the object (with keys and values), using the code reference by #Markus R and #James Moran comment, just use:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
.map(key => newO[key] = list[key]);
console.log(newO); // {bar: 15, me: 75, you: 100, foo: 116}

<pre>
function sortObjectByVal(obj){
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
newObj[x] = obj[x];
}
return newObj;
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>

Object sorted by value (DESC)
function sortObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
sortable.sort(function(a, b) {
return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
});
var orderedList = {};
for (var i = 0; i < sortable.length; i++) {
orderedList[sortable[i][0]] = sortable[i][1];
}
return orderedList;
}

a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
.sort((c,b) => {
return a[b]-a[c]
})
.reduce((acc, cur) => {
let o = {}
o[cur] = a[cur]
acc.push(o)
return acc
} , [])
output = [ { p: 8 }, { c: 2 }, { b: 1 }, { g: 1 } ]

var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
tmpList[key] = list[key];
delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }

TypeScript
The following function sorts object by value or a property of the value. If you don't use TypeScript you can remove the type information to convert it to JavaScript.
/**
* Represents an associative array of a same type.
*/
interface Dictionary<T> {
[key: string]: T;
}
/**
* Sorts an object (dictionary) by value or property of value and returns
* the sorted result as a Map object to preserve the sort order.
*/
function sort<TValue>(
obj: Dictionary<TValue>,
valSelector: (val: TValue) => number | string,
) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
Usage
var list = {
"one": { height: 100, weight: 15 },
"two": { height: 75, weight: 12 },
"three": { height: 116, weight: 9 },
"four": { height: 15, weight: 10 },
};
var sortedMap = sort(list, val => val.height);
The order of keys in a JavaScript object are not guaranteed, so I'm sorting and returning the result as a Map object which preserves the sort order.
If you want to convert it back to Object, you can do this:
var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });

const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]
const order = ['test2', 'test']
const setOrder = (arrayOfObjects, order) =>
arrayOfObjects.sort((a, b) => {
if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
return -1;
}
if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
return 1;
}
return 0;
});

my solution with sort :
let list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);
for(let element of sorted) {
console.log(element[0]+ ": " + element[1]);
}

A follow up answer to a long outdated question. I wrote two functions, one in which it sorts by keys, and the other by values, and returns the object in its sorted form in both functions. It should also work on strings as that is the reason why I am posting this (was having difficulty with some of the above on sorting by values if the values weren't numeric).
const a = {
absolutely: "works",
entirely: 'zen',
best: 'player',
average: 'joe'
}
const prop_sort = obj => {
return Object.keys(obj)
.sort()
.reduce((a, v) => {
a[v] = obj[v];
return a;
}, {});
}
const value_sort = obj => {
const ret = {}
Object.values(obj)
.sort()
.forEach(val => {
const key = Object.keys(obj).find(key => obj[key] == val)
ret[key] = val
})
return ret
}
console.log(prop_sort(a))
console.log(value_sort(a))

many similar and useful functions:
https://github.com/shimondoodkin/groupbyfunctions/
function sortobj(obj)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
function sortobjkey(obj,key)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
k=key; if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}

Here is one more example:
function sortObject(obj) {
var arr = [];
var prop;
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) {
return a.value - b.value;
});
return arr; // returns array
}
var list = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
var arr = sortObject(list);
console.log(arr);

Related

JS: Arrange array according to frequency with the most frequency at the top [duplicate]

If I have a JavaScript object such as:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
Is there a way to sort the properties based on value? So that I end up with
list = {
"bar": 15,
"me": 75,
"you": 100,
"foo": 116
};
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);
In ES10, you can use Object.fromEntries() to convert array to object. Then the code can be simplified to this:
const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
const sortable = Object.fromEntries(
Object.entries(maxSpeed).sort(([,a],[,b]) => a-b)
);
console.log(sortable);
We don't want to duplicate the entire data structure, or use an array where we need an associative array.
Here's another way to do the same thing as bonna:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted); // bar,me,you,foo
Your objects can have any amount of properties and you can choose to sort by whatever object property you want, number or string, if you put the objects in an array. Consider this array:
var arrayOfObjects = [
{
name: 'Diana',
born: 1373925600000, // Mon, Jul 15 2013
num: 4,
sex: 'female'
},
{
name: 'Beyonce',
born: 1366832953000, // Wed, Apr 24 2013
num: 2,
sex: 'female'
},
{
name: 'Albert',
born: 1370288700000, // Mon, Jun 3 2013
num: 3,
sex: 'male'
},
{
name: 'Doris',
born: 1354412087000, // Sat, Dec 1 2012
num: 1,
sex: 'female'
}
];
sort by date born, oldest first
// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
return a.born - b.born;
});
console.log('by date:');
console.log(byDate);
sort by name
var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
return x < y ? -1 : x > y ? 1 : 0;
});
console.log('by name:');
console.log(byName);
http://jsfiddle.net/xsM5s/16/
ECMAScript 2017 introduces Object.values / Object.entries. As the name suggests, the former aggregates all the values of an object into an array, and the latter does the whole object into an array of [key, value] arrays; Python's equivalent of dict.values() and dict.items().
The features make it pretty easier to sort any hash into an ordered object. As of now, only a small portion of JavaScript platforms support them, but you can try it on Firefox 47+.
EDIT: Now supported by all modern browsers!
let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]
let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]
For completeness sake, this function returns sorted array of object properties:
function sortObject(obj) {
var arr = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) { return a.value - b.value; });
//arr.sort(function(a, b) { return a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
return arr; // returns array
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]
JSFiddle with the code above is here. This solution is based on this article.
Updated fiddle for sorting strings is here. You can remove both additional .toLowerCase() conversions from it for case sensitive string comparation.
An "arrowed" version of #marcusR 's answer for reference
var myObj = { you: 100, me: 75, foo: 116, bar: 15 };
keysSorted = Object.keys(myObj).sort((a, b) => myObj[a] - myObj[b]);
alert(keysSorted); // bar,me,you,foo
UPDATE: April 2017
This returns a sorted myObj object defined above.
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result =
Object.keys(myObj)
.sort((a, b) => myObj[a] - myObj[b])
.reduce(
(_sortedObj, key) => ({
..._sortedObj,
[key]: myObj[key]
}),
{}
);
document.write(JSON.stringify(result));
UPDATE: March 2021 - Object.entries with sort function (updated as per comments)
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result = Object
.entries(myObj)
.sort((a, b) => a[1] - b[1])
.reduce((_sortedObj, [k,v]) => ({
..._sortedObj,
[k]: v
}), {})
document.write(JSON.stringify(result));
JavaScript objects are unordered by definition (see the ECMAScript Language
Specification, section 8.6). The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you need things to be ordered, use an array and the Array.prototype.sort method.
OK, as you may know, javascript has sort() function, to sort arrays, but nothing for object...
So in that case, we need to somehow get array of the keys and sort them, thats the reason the apis gives you objects in an array most of the time, because Array has more native functions to play with them than object literal, anyway, the quick solotion is using Object.key which return an array of the object keys, I create the ES6 function below which does the job for you, it uses native sort() and reduce() functions in javascript:
function sortObject(obj) {
return Object.keys(obj)
.sort().reduce((a, v) => {
a[v] = obj[v];
return a; }, {});
}
And now you can use it like this:
let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);
Check the sortedMyObject and you can see the result sorted by keys like this:
{a: 1, b: 2, c: 3, d: 4, e: 5}
Also this way, the main object won't be touched and we actually getting a new object.
I also create the image below, to make the function steps more clear, in case you need to change it a bit to work it your way:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
function sortAssocObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
// [["you",100],["me",75],["foo",116],["bar",15]]
sortable.sort(function(a, b) {
return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
});
// [["bar",15],["me",75],["you",100],["foo",116]]
var orderedList = {};
for (var idx in sortable) {
orderedList[sortable[idx][0]] = sortable[idx][1];
}
return orderedList;
}
sortAssocObject(list);
// {bar: 15, me: 75, you: 100, foo: 116}
Update with ES6: If your concern is having a sorted object to iterate through (which is why i'd imagine you want your object properties sorted), you can use the Map object.
You can insert your (key, value) pairs in sorted order and then doing a for..of loop will guarantee having them loop in the order you inserted them
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
// 0 = zero
// 1 = one
Sort values without multiple for-loops (to sort by the keys change index in the sort callback to "0")
const list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.fromEntries(
Object.entries(list).sort( (a,b) => a[1] - b[1] )
)
console.log('Sorted object: ', sorted)
Very short and simple!
var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
sortedList[key] = list[key]; });
Underscore.js or Lodash.js for advanced array or object sorts
var data = {
"models": {
"LTI": [
"TX"
],
"Carado": [
"A",
"T",
"A(пасс)",
"A(груз)",
"T(пасс)",
"T(груз)",
"A",
"T"
],
"SPARK": [
"SP110C 2",
"sp150r 18"
],
"Autobianchi": [
"A112"
]
}
};
var arr = [],
obj = {};
for (var i in data.models) {
arr.push([i, _.sortBy(data.models[i], function(el) {
return el;
})]);
}
arr = _.sortBy(arr, function(el) {
return el[0];
});
_.map(arr, function(el) {
return obj[el[0]] = el[1];
});
console.log(obj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js" integrity="sha256-qXBd/EfAdjOA2FGrGAG+b3YBn2tn5A6bhz+LSgYD96k=" crossorigin="anonymous"></script>
I am following the solution given by slebetman (go read it for all the details), but adjusted, since your object is non-nested.
// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
sort_array.push({key:key,value:list[key]});
}
// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});
// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
var item = list[sort_array[i].key];
// now do stuff with each item
}
let toSort = {a:2323, b: 14, c: 799}
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1])
Output:
[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]
There are many ways to do this, but since I didn't see any using reduce() I put it here. Maybe it seems utils to someone.
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let result = Object.keys(list).sort((a,b)=>list[a]>list[b]?1:-1).reduce((a,b)=> {a[b]=list[b]; return a},{});
console.log(result);
Thanks to #orad for providing the answer in TypeScript. Now, We can use the below codesnippet in JavaScript.
function sort(obj,valSelector) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
const Countries = { "AD": { "name": "Andorra", }, "AE": { "name": "United Arab Emirates", }, "IN": { "name": "India", }}
// Sort the object inside object.
var sortedMap = sort(Countries, val => val.name);
// Convert to object.
var sortedObj = {};
sortedMap.forEach((v,k) => { sortedObj[k] = v }); console.log(sortedObj);
//Output: {"AD": {"name": "Andorra"},"IN": {"name": "India"},"AE": {"name": "United Arab Emirates"}}
Sorting object property by values
const obj = { you: 100, me: 75, foo: 116, bar: 15 };
const keysSorted = Object.keys(obj).sort((a, b) => obj[a] - obj[b]);
const result = {};
keysSorted.forEach(key => { result[key] = obj[key]; });
document.write('Result: ' + JSON.stringify(result));
The desired output:
{"bar":15,"me":75,"you":100,"foo":116}
References:
Sorting object property by values
Convert array into object
This could be a simple way to handle it as a real ordered object. Not sure how slow it is. also might be better with a while loop.
Object.sortByKeys = function(myObj){
var keys = Object.keys(myObj)
keys.sort()
var sortedObject = Object()
for(i in keys){
key = keys[i]
sortedObject[key]=myObj[key]
}
return sortedObject
}
And then I found this invert function from:
http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/
Object.invert = function (obj) {
var new_obj = {};
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
new_obj[obj[prop]] = prop;
}
}
return new_obj;
};
So
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)
Just in case, someone is looking for keeping the object (with keys and values), using the code reference by #Markus R and #James Moran comment, just use:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
.map(key => newO[key] = list[key]);
console.log(newO); // {bar: 15, me: 75, you: 100, foo: 116}
<pre>
function sortObjectByVal(obj){
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
newObj[x] = obj[x];
}
return newObj;
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>
Object sorted by value (DESC)
function sortObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
sortable.sort(function(a, b) {
return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
});
var orderedList = {};
for (var i = 0; i < sortable.length; i++) {
orderedList[sortable[i][0]] = sortable[i][1];
}
return orderedList;
}
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
.sort((c,b) => {
return a[b]-a[c]
})
.reduce((acc, cur) => {
let o = {}
o[cur] = a[cur]
acc.push(o)
return acc
} , [])
output = [ { p: 8 }, { c: 2 }, { b: 1 }, { g: 1 } ]
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
tmpList[key] = list[key];
delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }
TypeScript
The following function sorts object by value or a property of the value. If you don't use TypeScript you can remove the type information to convert it to JavaScript.
/**
* Represents an associative array of a same type.
*/
interface Dictionary<T> {
[key: string]: T;
}
/**
* Sorts an object (dictionary) by value or property of value and returns
* the sorted result as a Map object to preserve the sort order.
*/
function sort<TValue>(
obj: Dictionary<TValue>,
valSelector: (val: TValue) => number | string,
) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
Usage
var list = {
"one": { height: 100, weight: 15 },
"two": { height: 75, weight: 12 },
"three": { height: 116, weight: 9 },
"four": { height: 15, weight: 10 },
};
var sortedMap = sort(list, val => val.height);
The order of keys in a JavaScript object are not guaranteed, so I'm sorting and returning the result as a Map object which preserves the sort order.
If you want to convert it back to Object, you can do this:
var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });
const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]
const order = ['test2', 'test']
const setOrder = (arrayOfObjects, order) =>
arrayOfObjects.sort((a, b) => {
if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
return -1;
}
if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
return 1;
}
return 0;
});
my solution with sort :
let list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);
for(let element of sorted) {
console.log(element[0]+ ": " + element[1]);
}
A follow up answer to a long outdated question. I wrote two functions, one in which it sorts by keys, and the other by values, and returns the object in its sorted form in both functions. It should also work on strings as that is the reason why I am posting this (was having difficulty with some of the above on sorting by values if the values weren't numeric).
const a = {
absolutely: "works",
entirely: 'zen',
best: 'player',
average: 'joe'
}
const prop_sort = obj => {
return Object.keys(obj)
.sort()
.reduce((a, v) => {
a[v] = obj[v];
return a;
}, {});
}
const value_sort = obj => {
const ret = {}
Object.values(obj)
.sort()
.forEach(val => {
const key = Object.keys(obj).find(key => obj[key] == val)
ret[key] = val
})
return ret
}
console.log(prop_sort(a))
console.log(value_sort(a))
many similar and useful functions:
https://github.com/shimondoodkin/groupbyfunctions/
function sortobj(obj)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
function sortobjkey(obj,key)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
k=key; if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
Here is one more example:
function sortObject(obj) {
var arr = [];
var prop;
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) {
return a.value - b.value;
});
return arr; // returns array
}
var list = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
var arr = sortObject(list);
console.log(arr);

How to sort an object using array of objects [duplicate]

If I have a JavaScript object such as:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
Is there a way to sort the properties based on value? So that I end up with
list = {
"bar": 15,
"me": 75,
"you": 100,
"foo": 116
};
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);
In ES10, you can use Object.fromEntries() to convert array to object. Then the code can be simplified to this:
const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
const sortable = Object.fromEntries(
Object.entries(maxSpeed).sort(([,a],[,b]) => a-b)
);
console.log(sortable);
We don't want to duplicate the entire data structure, or use an array where we need an associative array.
Here's another way to do the same thing as bonna:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted); // bar,me,you,foo
Your objects can have any amount of properties and you can choose to sort by whatever object property you want, number or string, if you put the objects in an array. Consider this array:
var arrayOfObjects = [
{
name: 'Diana',
born: 1373925600000, // Mon, Jul 15 2013
num: 4,
sex: 'female'
},
{
name: 'Beyonce',
born: 1366832953000, // Wed, Apr 24 2013
num: 2,
sex: 'female'
},
{
name: 'Albert',
born: 1370288700000, // Mon, Jun 3 2013
num: 3,
sex: 'male'
},
{
name: 'Doris',
born: 1354412087000, // Sat, Dec 1 2012
num: 1,
sex: 'female'
}
];
sort by date born, oldest first
// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
return a.born - b.born;
});
console.log('by date:');
console.log(byDate);
sort by name
var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
return x < y ? -1 : x > y ? 1 : 0;
});
console.log('by name:');
console.log(byName);
http://jsfiddle.net/xsM5s/16/
ECMAScript 2017 introduces Object.values / Object.entries. As the name suggests, the former aggregates all the values of an object into an array, and the latter does the whole object into an array of [key, value] arrays; Python's equivalent of dict.values() and dict.items().
The features make it pretty easier to sort any hash into an ordered object. As of now, only a small portion of JavaScript platforms support them, but you can try it on Firefox 47+.
EDIT: Now supported by all modern browsers!
let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]
let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]
For completeness sake, this function returns sorted array of object properties:
function sortObject(obj) {
var arr = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) { return a.value - b.value; });
//arr.sort(function(a, b) { return a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
return arr; // returns array
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]
JSFiddle with the code above is here. This solution is based on this article.
Updated fiddle for sorting strings is here. You can remove both additional .toLowerCase() conversions from it for case sensitive string comparation.
An "arrowed" version of #marcusR 's answer for reference
var myObj = { you: 100, me: 75, foo: 116, bar: 15 };
keysSorted = Object.keys(myObj).sort((a, b) => myObj[a] - myObj[b]);
alert(keysSorted); // bar,me,you,foo
UPDATE: April 2017
This returns a sorted myObj object defined above.
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result =
Object.keys(myObj)
.sort((a, b) => myObj[a] - myObj[b])
.reduce(
(_sortedObj, key) => ({
..._sortedObj,
[key]: myObj[key]
}),
{}
);
document.write(JSON.stringify(result));
UPDATE: March 2021 - Object.entries with sort function (updated as per comments)
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result = Object
.entries(myObj)
.sort((a, b) => a[1] - b[1])
.reduce((_sortedObj, [k,v]) => ({
..._sortedObj,
[k]: v
}), {})
document.write(JSON.stringify(result));
JavaScript objects are unordered by definition (see the ECMAScript Language
Specification, section 8.6). The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you need things to be ordered, use an array and the Array.prototype.sort method.
OK, as you may know, javascript has sort() function, to sort arrays, but nothing for object...
So in that case, we need to somehow get array of the keys and sort them, thats the reason the apis gives you objects in an array most of the time, because Array has more native functions to play with them than object literal, anyway, the quick solotion is using Object.key which return an array of the object keys, I create the ES6 function below which does the job for you, it uses native sort() and reduce() functions in javascript:
function sortObject(obj) {
return Object.keys(obj)
.sort().reduce((a, v) => {
a[v] = obj[v];
return a; }, {});
}
And now you can use it like this:
let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);
Check the sortedMyObject and you can see the result sorted by keys like this:
{a: 1, b: 2, c: 3, d: 4, e: 5}
Also this way, the main object won't be touched and we actually getting a new object.
I also create the image below, to make the function steps more clear, in case you need to change it a bit to work it your way:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
function sortAssocObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
// [["you",100],["me",75],["foo",116],["bar",15]]
sortable.sort(function(a, b) {
return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
});
// [["bar",15],["me",75],["you",100],["foo",116]]
var orderedList = {};
for (var idx in sortable) {
orderedList[sortable[idx][0]] = sortable[idx][1];
}
return orderedList;
}
sortAssocObject(list);
// {bar: 15, me: 75, you: 100, foo: 116}
Update with ES6: If your concern is having a sorted object to iterate through (which is why i'd imagine you want your object properties sorted), you can use the Map object.
You can insert your (key, value) pairs in sorted order and then doing a for..of loop will guarantee having them loop in the order you inserted them
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
// 0 = zero
// 1 = one
Sort values without multiple for-loops (to sort by the keys change index in the sort callback to "0")
const list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.fromEntries(
Object.entries(list).sort( (a,b) => a[1] - b[1] )
)
console.log('Sorted object: ', sorted)
Very short and simple!
var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
sortedList[key] = list[key]; });
Underscore.js or Lodash.js for advanced array or object sorts
var data = {
"models": {
"LTI": [
"TX"
],
"Carado": [
"A",
"T",
"A(пасс)",
"A(груз)",
"T(пасс)",
"T(груз)",
"A",
"T"
],
"SPARK": [
"SP110C 2",
"sp150r 18"
],
"Autobianchi": [
"A112"
]
}
};
var arr = [],
obj = {};
for (var i in data.models) {
arr.push([i, _.sortBy(data.models[i], function(el) {
return el;
})]);
}
arr = _.sortBy(arr, function(el) {
return el[0];
});
_.map(arr, function(el) {
return obj[el[0]] = el[1];
});
console.log(obj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js" integrity="sha256-qXBd/EfAdjOA2FGrGAG+b3YBn2tn5A6bhz+LSgYD96k=" crossorigin="anonymous"></script>
I am following the solution given by slebetman (go read it for all the details), but adjusted, since your object is non-nested.
// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
sort_array.push({key:key,value:list[key]});
}
// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});
// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
var item = list[sort_array[i].key];
// now do stuff with each item
}
let toSort = {a:2323, b: 14, c: 799}
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1])
Output:
[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]
There are many ways to do this, but since I didn't see any using reduce() I put it here. Maybe it seems utils to someone.
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let result = Object.keys(list).sort((a,b)=>list[a]>list[b]?1:-1).reduce((a,b)=> {a[b]=list[b]; return a},{});
console.log(result);
Thanks to #orad for providing the answer in TypeScript. Now, We can use the below codesnippet in JavaScript.
function sort(obj,valSelector) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
const Countries = { "AD": { "name": "Andorra", }, "AE": { "name": "United Arab Emirates", }, "IN": { "name": "India", }}
// Sort the object inside object.
var sortedMap = sort(Countries, val => val.name);
// Convert to object.
var sortedObj = {};
sortedMap.forEach((v,k) => { sortedObj[k] = v }); console.log(sortedObj);
//Output: {"AD": {"name": "Andorra"},"IN": {"name": "India"},"AE": {"name": "United Arab Emirates"}}
Sorting object property by values
const obj = { you: 100, me: 75, foo: 116, bar: 15 };
const keysSorted = Object.keys(obj).sort((a, b) => obj[a] - obj[b]);
const result = {};
keysSorted.forEach(key => { result[key] = obj[key]; });
document.write('Result: ' + JSON.stringify(result));
The desired output:
{"bar":15,"me":75,"you":100,"foo":116}
References:
Sorting object property by values
Convert array into object
This could be a simple way to handle it as a real ordered object. Not sure how slow it is. also might be better with a while loop.
Object.sortByKeys = function(myObj){
var keys = Object.keys(myObj)
keys.sort()
var sortedObject = Object()
for(i in keys){
key = keys[i]
sortedObject[key]=myObj[key]
}
return sortedObject
}
And then I found this invert function from:
http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/
Object.invert = function (obj) {
var new_obj = {};
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
new_obj[obj[prop]] = prop;
}
}
return new_obj;
};
So
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)
Just in case, someone is looking for keeping the object (with keys and values), using the code reference by #Markus R and #James Moran comment, just use:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
.map(key => newO[key] = list[key]);
console.log(newO); // {bar: 15, me: 75, you: 100, foo: 116}
<pre>
function sortObjectByVal(obj){
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
newObj[x] = obj[x];
}
return newObj;
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>
Object sorted by value (DESC)
function sortObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
sortable.sort(function(a, b) {
return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
});
var orderedList = {};
for (var i = 0; i < sortable.length; i++) {
orderedList[sortable[i][0]] = sortable[i][1];
}
return orderedList;
}
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
.sort((c,b) => {
return a[b]-a[c]
})
.reduce((acc, cur) => {
let o = {}
o[cur] = a[cur]
acc.push(o)
return acc
} , [])
output = [ { p: 8 }, { c: 2 }, { b: 1 }, { g: 1 } ]
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
tmpList[key] = list[key];
delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }
TypeScript
The following function sorts object by value or a property of the value. If you don't use TypeScript you can remove the type information to convert it to JavaScript.
/**
* Represents an associative array of a same type.
*/
interface Dictionary<T> {
[key: string]: T;
}
/**
* Sorts an object (dictionary) by value or property of value and returns
* the sorted result as a Map object to preserve the sort order.
*/
function sort<TValue>(
obj: Dictionary<TValue>,
valSelector: (val: TValue) => number | string,
) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
Usage
var list = {
"one": { height: 100, weight: 15 },
"two": { height: 75, weight: 12 },
"three": { height: 116, weight: 9 },
"four": { height: 15, weight: 10 },
};
var sortedMap = sort(list, val => val.height);
The order of keys in a JavaScript object are not guaranteed, so I'm sorting and returning the result as a Map object which preserves the sort order.
If you want to convert it back to Object, you can do this:
var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });
const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]
const order = ['test2', 'test']
const setOrder = (arrayOfObjects, order) =>
arrayOfObjects.sort((a, b) => {
if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
return -1;
}
if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
return 1;
}
return 0;
});
my solution with sort :
let list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);
for(let element of sorted) {
console.log(element[0]+ ": " + element[1]);
}
A follow up answer to a long outdated question. I wrote two functions, one in which it sorts by keys, and the other by values, and returns the object in its sorted form in both functions. It should also work on strings as that is the reason why I am posting this (was having difficulty with some of the above on sorting by values if the values weren't numeric).
const a = {
absolutely: "works",
entirely: 'zen',
best: 'player',
average: 'joe'
}
const prop_sort = obj => {
return Object.keys(obj)
.sort()
.reduce((a, v) => {
a[v] = obj[v];
return a;
}, {});
}
const value_sort = obj => {
const ret = {}
Object.values(obj)
.sort()
.forEach(val => {
const key = Object.keys(obj).find(key => obj[key] == val)
ret[key] = val
})
return ret
}
console.log(prop_sort(a))
console.log(value_sort(a))
many similar and useful functions:
https://github.com/shimondoodkin/groupbyfunctions/
function sortobj(obj)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
function sortobjkey(obj,key)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
k=key; if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
Here is one more example:
function sortObject(obj) {
var arr = [];
var prop;
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) {
return a.value - b.value;
});
return arr; // returns array
}
var list = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
var arr = sortObject(list);
console.log(arr);

Sorting json by numeric key [duplicate]

If I have a JavaScript object such as:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
Is there a way to sort the properties based on value? So that I end up with
list = {
"bar": 15,
"me": 75,
"you": 100,
"foo": 116
};
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);
In ES10, you can use Object.fromEntries() to convert array to object. Then the code can be simplified to this:
const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
const sortable = Object.fromEntries(
Object.entries(maxSpeed).sort(([,a],[,b]) => a-b)
);
console.log(sortable);
We don't want to duplicate the entire data structure, or use an array where we need an associative array.
Here's another way to do the same thing as bonna:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted); // bar,me,you,foo
Your objects can have any amount of properties and you can choose to sort by whatever object property you want, number or string, if you put the objects in an array. Consider this array:
var arrayOfObjects = [
{
name: 'Diana',
born: 1373925600000, // Mon, Jul 15 2013
num: 4,
sex: 'female'
},
{
name: 'Beyonce',
born: 1366832953000, // Wed, Apr 24 2013
num: 2,
sex: 'female'
},
{
name: 'Albert',
born: 1370288700000, // Mon, Jun 3 2013
num: 3,
sex: 'male'
},
{
name: 'Doris',
born: 1354412087000, // Sat, Dec 1 2012
num: 1,
sex: 'female'
}
];
sort by date born, oldest first
// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
return a.born - b.born;
});
console.log('by date:');
console.log(byDate);
sort by name
var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
return x < y ? -1 : x > y ? 1 : 0;
});
console.log('by name:');
console.log(byName);
http://jsfiddle.net/xsM5s/16/
ECMAScript 2017 introduces Object.values / Object.entries. As the name suggests, the former aggregates all the values of an object into an array, and the latter does the whole object into an array of [key, value] arrays; Python's equivalent of dict.values() and dict.items().
The features make it pretty easier to sort any hash into an ordered object. As of now, only a small portion of JavaScript platforms support them, but you can try it on Firefox 47+.
EDIT: Now supported by all modern browsers!
let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]
let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]
For completeness sake, this function returns sorted array of object properties:
function sortObject(obj) {
var arr = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) { return a.value - b.value; });
//arr.sort(function(a, b) { return a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
return arr; // returns array
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]
JSFiddle with the code above is here. This solution is based on this article.
Updated fiddle for sorting strings is here. You can remove both additional .toLowerCase() conversions from it for case sensitive string comparation.
An "arrowed" version of #marcusR 's answer for reference
var myObj = { you: 100, me: 75, foo: 116, bar: 15 };
keysSorted = Object.keys(myObj).sort((a, b) => myObj[a] - myObj[b]);
alert(keysSorted); // bar,me,you,foo
UPDATE: April 2017
This returns a sorted myObj object defined above.
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result =
Object.keys(myObj)
.sort((a, b) => myObj[a] - myObj[b])
.reduce(
(_sortedObj, key) => ({
..._sortedObj,
[key]: myObj[key]
}),
{}
);
document.write(JSON.stringify(result));
UPDATE: March 2021 - Object.entries with sort function (updated as per comments)
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result = Object
.entries(myObj)
.sort((a, b) => a[1] - b[1])
.reduce((_sortedObj, [k,v]) => ({
..._sortedObj,
[k]: v
}), {})
document.write(JSON.stringify(result));
JavaScript objects are unordered by definition (see the ECMAScript Language
Specification, section 8.6). The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you need things to be ordered, use an array and the Array.prototype.sort method.
OK, as you may know, javascript has sort() function, to sort arrays, but nothing for object...
So in that case, we need to somehow get array of the keys and sort them, thats the reason the apis gives you objects in an array most of the time, because Array has more native functions to play with them than object literal, anyway, the quick solotion is using Object.key which return an array of the object keys, I create the ES6 function below which does the job for you, it uses native sort() and reduce() functions in javascript:
function sortObject(obj) {
return Object.keys(obj)
.sort().reduce((a, v) => {
a[v] = obj[v];
return a; }, {});
}
And now you can use it like this:
let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);
Check the sortedMyObject and you can see the result sorted by keys like this:
{a: 1, b: 2, c: 3, d: 4, e: 5}
Also this way, the main object won't be touched and we actually getting a new object.
I also create the image below, to make the function steps more clear, in case you need to change it a bit to work it your way:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
function sortAssocObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
// [["you",100],["me",75],["foo",116],["bar",15]]
sortable.sort(function(a, b) {
return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
});
// [["bar",15],["me",75],["you",100],["foo",116]]
var orderedList = {};
for (var idx in sortable) {
orderedList[sortable[idx][0]] = sortable[idx][1];
}
return orderedList;
}
sortAssocObject(list);
// {bar: 15, me: 75, you: 100, foo: 116}
Update with ES6: If your concern is having a sorted object to iterate through (which is why i'd imagine you want your object properties sorted), you can use the Map object.
You can insert your (key, value) pairs in sorted order and then doing a for..of loop will guarantee having them loop in the order you inserted them
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
// 0 = zero
// 1 = one
Sort values without multiple for-loops (to sort by the keys change index in the sort callback to "0")
const list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.fromEntries(
Object.entries(list).sort( (a,b) => a[1] - b[1] )
)
console.log('Sorted object: ', sorted)
Very short and simple!
var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
sortedList[key] = list[key]; });
Underscore.js or Lodash.js for advanced array or object sorts
var data = {
"models": {
"LTI": [
"TX"
],
"Carado": [
"A",
"T",
"A(пасс)",
"A(груз)",
"T(пасс)",
"T(груз)",
"A",
"T"
],
"SPARK": [
"SP110C 2",
"sp150r 18"
],
"Autobianchi": [
"A112"
]
}
};
var arr = [],
obj = {};
for (var i in data.models) {
arr.push([i, _.sortBy(data.models[i], function(el) {
return el;
})]);
}
arr = _.sortBy(arr, function(el) {
return el[0];
});
_.map(arr, function(el) {
return obj[el[0]] = el[1];
});
console.log(obj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js" integrity="sha256-qXBd/EfAdjOA2FGrGAG+b3YBn2tn5A6bhz+LSgYD96k=" crossorigin="anonymous"></script>
I am following the solution given by slebetman (go read it for all the details), but adjusted, since your object is non-nested.
// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
sort_array.push({key:key,value:list[key]});
}
// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});
// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
var item = list[sort_array[i].key];
// now do stuff with each item
}
let toSort = {a:2323, b: 14, c: 799}
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1])
Output:
[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]
There are many ways to do this, but since I didn't see any using reduce() I put it here. Maybe it seems utils to someone.
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let result = Object.keys(list).sort((a,b)=>list[a]>list[b]?1:-1).reduce((a,b)=> {a[b]=list[b]; return a},{});
console.log(result);
Thanks to #orad for providing the answer in TypeScript. Now, We can use the below codesnippet in JavaScript.
function sort(obj,valSelector) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
const Countries = { "AD": { "name": "Andorra", }, "AE": { "name": "United Arab Emirates", }, "IN": { "name": "India", }}
// Sort the object inside object.
var sortedMap = sort(Countries, val => val.name);
// Convert to object.
var sortedObj = {};
sortedMap.forEach((v,k) => { sortedObj[k] = v }); console.log(sortedObj);
//Output: {"AD": {"name": "Andorra"},"IN": {"name": "India"},"AE": {"name": "United Arab Emirates"}}
Sorting object property by values
const obj = { you: 100, me: 75, foo: 116, bar: 15 };
const keysSorted = Object.keys(obj).sort((a, b) => obj[a] - obj[b]);
const result = {};
keysSorted.forEach(key => { result[key] = obj[key]; });
document.write('Result: ' + JSON.stringify(result));
The desired output:
{"bar":15,"me":75,"you":100,"foo":116}
References:
Sorting object property by values
Convert array into object
This could be a simple way to handle it as a real ordered object. Not sure how slow it is. also might be better with a while loop.
Object.sortByKeys = function(myObj){
var keys = Object.keys(myObj)
keys.sort()
var sortedObject = Object()
for(i in keys){
key = keys[i]
sortedObject[key]=myObj[key]
}
return sortedObject
}
And then I found this invert function from:
http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/
Object.invert = function (obj) {
var new_obj = {};
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
new_obj[obj[prop]] = prop;
}
}
return new_obj;
};
So
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)
Just in case, someone is looking for keeping the object (with keys and values), using the code reference by #Markus R and #James Moran comment, just use:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
.map(key => newO[key] = list[key]);
console.log(newO); // {bar: 15, me: 75, you: 100, foo: 116}
<pre>
function sortObjectByVal(obj){
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
newObj[x] = obj[x];
}
return newObj;
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>
Object sorted by value (DESC)
function sortObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
sortable.sort(function(a, b) {
return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
});
var orderedList = {};
for (var i = 0; i < sortable.length; i++) {
orderedList[sortable[i][0]] = sortable[i][1];
}
return orderedList;
}
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
.sort((c,b) => {
return a[b]-a[c]
})
.reduce((acc, cur) => {
let o = {}
o[cur] = a[cur]
acc.push(o)
return acc
} , [])
output = [ { p: 8 }, { c: 2 }, { b: 1 }, { g: 1 } ]
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
tmpList[key] = list[key];
delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }
TypeScript
The following function sorts object by value or a property of the value. If you don't use TypeScript you can remove the type information to convert it to JavaScript.
/**
* Represents an associative array of a same type.
*/
interface Dictionary<T> {
[key: string]: T;
}
/**
* Sorts an object (dictionary) by value or property of value and returns
* the sorted result as a Map object to preserve the sort order.
*/
function sort<TValue>(
obj: Dictionary<TValue>,
valSelector: (val: TValue) => number | string,
) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
Usage
var list = {
"one": { height: 100, weight: 15 },
"two": { height: 75, weight: 12 },
"three": { height: 116, weight: 9 },
"four": { height: 15, weight: 10 },
};
var sortedMap = sort(list, val => val.height);
The order of keys in a JavaScript object are not guaranteed, so I'm sorting and returning the result as a Map object which preserves the sort order.
If you want to convert it back to Object, you can do this:
var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });
const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]
const order = ['test2', 'test']
const setOrder = (arrayOfObjects, order) =>
arrayOfObjects.sort((a, b) => {
if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
return -1;
}
if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
return 1;
}
return 0;
});
my solution with sort :
let list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);
for(let element of sorted) {
console.log(element[0]+ ": " + element[1]);
}
A follow up answer to a long outdated question. I wrote two functions, one in which it sorts by keys, and the other by values, and returns the object in its sorted form in both functions. It should also work on strings as that is the reason why I am posting this (was having difficulty with some of the above on sorting by values if the values weren't numeric).
const a = {
absolutely: "works",
entirely: 'zen',
best: 'player',
average: 'joe'
}
const prop_sort = obj => {
return Object.keys(obj)
.sort()
.reduce((a, v) => {
a[v] = obj[v];
return a;
}, {});
}
const value_sort = obj => {
const ret = {}
Object.values(obj)
.sort()
.forEach(val => {
const key = Object.keys(obj).find(key => obj[key] == val)
ret[key] = val
})
return ret
}
console.log(prop_sort(a))
console.log(value_sort(a))
many similar and useful functions:
https://github.com/shimondoodkin/groupbyfunctions/
function sortobj(obj)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
function sortobjkey(obj,key)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
k=key; if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
Here is one more example:
function sortObject(obj) {
var arr = [];
var prop;
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) {
return a.value - b.value;
});
return arr; // returns array
}
var list = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
var arr = sortObject(list);
console.log(arr);

Javascript Object Sorting by it's Index key value [duplicate]

If I have a JavaScript object such as:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
Is there a way to sort the properties based on value? So that I end up with
list = {
"bar": 15,
"me": 75,
"you": 100,
"foo": 116
};
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);
In ES10, you can use Object.fromEntries() to convert array to object. Then the code can be simplified to this:
const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
const sortable = Object.fromEntries(
Object.entries(maxSpeed).sort(([,a],[,b]) => a-b)
);
console.log(sortable);
We don't want to duplicate the entire data structure, or use an array where we need an associative array.
Here's another way to do the same thing as bonna:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted); // bar,me,you,foo
Your objects can have any amount of properties and you can choose to sort by whatever object property you want, number or string, if you put the objects in an array. Consider this array:
var arrayOfObjects = [
{
name: 'Diana',
born: 1373925600000, // Mon, Jul 15 2013
num: 4,
sex: 'female'
},
{
name: 'Beyonce',
born: 1366832953000, // Wed, Apr 24 2013
num: 2,
sex: 'female'
},
{
name: 'Albert',
born: 1370288700000, // Mon, Jun 3 2013
num: 3,
sex: 'male'
},
{
name: 'Doris',
born: 1354412087000, // Sat, Dec 1 2012
num: 1,
sex: 'female'
}
];
sort by date born, oldest first
// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
return a.born - b.born;
});
console.log('by date:');
console.log(byDate);
sort by name
var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
return x < y ? -1 : x > y ? 1 : 0;
});
console.log('by name:');
console.log(byName);
http://jsfiddle.net/xsM5s/16/
ECMAScript 2017 introduces Object.values / Object.entries. As the name suggests, the former aggregates all the values of an object into an array, and the latter does the whole object into an array of [key, value] arrays; Python's equivalent of dict.values() and dict.items().
The features make it pretty easier to sort any hash into an ordered object. As of now, only a small portion of JavaScript platforms support them, but you can try it on Firefox 47+.
EDIT: Now supported by all modern browsers!
let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]
let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]
For completeness sake, this function returns sorted array of object properties:
function sortObject(obj) {
var arr = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) { return a.value - b.value; });
//arr.sort(function(a, b) { return a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
return arr; // returns array
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]
JSFiddle with the code above is here. This solution is based on this article.
Updated fiddle for sorting strings is here. You can remove both additional .toLowerCase() conversions from it for case sensitive string comparation.
An "arrowed" version of #marcusR 's answer for reference
var myObj = { you: 100, me: 75, foo: 116, bar: 15 };
keysSorted = Object.keys(myObj).sort((a, b) => myObj[a] - myObj[b]);
alert(keysSorted); // bar,me,you,foo
UPDATE: April 2017
This returns a sorted myObj object defined above.
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result =
Object.keys(myObj)
.sort((a, b) => myObj[a] - myObj[b])
.reduce(
(_sortedObj, key) => ({
..._sortedObj,
[key]: myObj[key]
}),
{}
);
document.write(JSON.stringify(result));
UPDATE: March 2021 - Object.entries with sort function (updated as per comments)
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result = Object
.entries(myObj)
.sort((a, b) => a[1] - b[1])
.reduce((_sortedObj, [k,v]) => ({
..._sortedObj,
[k]: v
}), {})
document.write(JSON.stringify(result));
JavaScript objects are unordered by definition (see the ECMAScript Language
Specification, section 8.6). The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you need things to be ordered, use an array and the Array.prototype.sort method.
OK, as you may know, javascript has sort() function, to sort arrays, but nothing for object...
So in that case, we need to somehow get array of the keys and sort them, thats the reason the apis gives you objects in an array most of the time, because Array has more native functions to play with them than object literal, anyway, the quick solotion is using Object.key which return an array of the object keys, I create the ES6 function below which does the job for you, it uses native sort() and reduce() functions in javascript:
function sortObject(obj) {
return Object.keys(obj)
.sort().reduce((a, v) => {
a[v] = obj[v];
return a; }, {});
}
And now you can use it like this:
let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);
Check the sortedMyObject and you can see the result sorted by keys like this:
{a: 1, b: 2, c: 3, d: 4, e: 5}
Also this way, the main object won't be touched and we actually getting a new object.
I also create the image below, to make the function steps more clear, in case you need to change it a bit to work it your way:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
function sortAssocObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
// [["you",100],["me",75],["foo",116],["bar",15]]
sortable.sort(function(a, b) {
return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
});
// [["bar",15],["me",75],["you",100],["foo",116]]
var orderedList = {};
for (var idx in sortable) {
orderedList[sortable[idx][0]] = sortable[idx][1];
}
return orderedList;
}
sortAssocObject(list);
// {bar: 15, me: 75, you: 100, foo: 116}
Update with ES6: If your concern is having a sorted object to iterate through (which is why i'd imagine you want your object properties sorted), you can use the Map object.
You can insert your (key, value) pairs in sorted order and then doing a for..of loop will guarantee having them loop in the order you inserted them
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
// 0 = zero
// 1 = one
Sort values without multiple for-loops (to sort by the keys change index in the sort callback to "0")
const list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.fromEntries(
Object.entries(list).sort( (a,b) => a[1] - b[1] )
)
console.log('Sorted object: ', sorted)
Very short and simple!
var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
sortedList[key] = list[key]; });
Underscore.js or Lodash.js for advanced array or object sorts
var data = {
"models": {
"LTI": [
"TX"
],
"Carado": [
"A",
"T",
"A(пасс)",
"A(груз)",
"T(пасс)",
"T(груз)",
"A",
"T"
],
"SPARK": [
"SP110C 2",
"sp150r 18"
],
"Autobianchi": [
"A112"
]
}
};
var arr = [],
obj = {};
for (var i in data.models) {
arr.push([i, _.sortBy(data.models[i], function(el) {
return el;
})]);
}
arr = _.sortBy(arr, function(el) {
return el[0];
});
_.map(arr, function(el) {
return obj[el[0]] = el[1];
});
console.log(obj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js" integrity="sha256-qXBd/EfAdjOA2FGrGAG+b3YBn2tn5A6bhz+LSgYD96k=" crossorigin="anonymous"></script>
I am following the solution given by slebetman (go read it for all the details), but adjusted, since your object is non-nested.
// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
sort_array.push({key:key,value:list[key]});
}
// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});
// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
var item = list[sort_array[i].key];
// now do stuff with each item
}
let toSort = {a:2323, b: 14, c: 799}
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1])
Output:
[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]
There are many ways to do this, but since I didn't see any using reduce() I put it here. Maybe it seems utils to someone.
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let result = Object.keys(list).sort((a,b)=>list[a]>list[b]?1:-1).reduce((a,b)=> {a[b]=list[b]; return a},{});
console.log(result);
Thanks to #orad for providing the answer in TypeScript. Now, We can use the below codesnippet in JavaScript.
function sort(obj,valSelector) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
const Countries = { "AD": { "name": "Andorra", }, "AE": { "name": "United Arab Emirates", }, "IN": { "name": "India", }}
// Sort the object inside object.
var sortedMap = sort(Countries, val => val.name);
// Convert to object.
var sortedObj = {};
sortedMap.forEach((v,k) => { sortedObj[k] = v }); console.log(sortedObj);
//Output: {"AD": {"name": "Andorra"},"IN": {"name": "India"},"AE": {"name": "United Arab Emirates"}}
Sorting object property by values
const obj = { you: 100, me: 75, foo: 116, bar: 15 };
const keysSorted = Object.keys(obj).sort((a, b) => obj[a] - obj[b]);
const result = {};
keysSorted.forEach(key => { result[key] = obj[key]; });
document.write('Result: ' + JSON.stringify(result));
The desired output:
{"bar":15,"me":75,"you":100,"foo":116}
References:
Sorting object property by values
Convert array into object
This could be a simple way to handle it as a real ordered object. Not sure how slow it is. also might be better with a while loop.
Object.sortByKeys = function(myObj){
var keys = Object.keys(myObj)
keys.sort()
var sortedObject = Object()
for(i in keys){
key = keys[i]
sortedObject[key]=myObj[key]
}
return sortedObject
}
And then I found this invert function from:
http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/
Object.invert = function (obj) {
var new_obj = {};
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
new_obj[obj[prop]] = prop;
}
}
return new_obj;
};
So
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)
Just in case, someone is looking for keeping the object (with keys and values), using the code reference by #Markus R and #James Moran comment, just use:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
.map(key => newO[key] = list[key]);
console.log(newO); // {bar: 15, me: 75, you: 100, foo: 116}
<pre>
function sortObjectByVal(obj){
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
newObj[x] = obj[x];
}
return newObj;
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>
Object sorted by value (DESC)
function sortObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
sortable.sort(function(a, b) {
return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
});
var orderedList = {};
for (var i = 0; i < sortable.length; i++) {
orderedList[sortable[i][0]] = sortable[i][1];
}
return orderedList;
}
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
.sort((c,b) => {
return a[b]-a[c]
})
.reduce((acc, cur) => {
let o = {}
o[cur] = a[cur]
acc.push(o)
return acc
} , [])
output = [ { p: 8 }, { c: 2 }, { b: 1 }, { g: 1 } ]
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
tmpList[key] = list[key];
delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }
TypeScript
The following function sorts object by value or a property of the value. If you don't use TypeScript you can remove the type information to convert it to JavaScript.
/**
* Represents an associative array of a same type.
*/
interface Dictionary<T> {
[key: string]: T;
}
/**
* Sorts an object (dictionary) by value or property of value and returns
* the sorted result as a Map object to preserve the sort order.
*/
function sort<TValue>(
obj: Dictionary<TValue>,
valSelector: (val: TValue) => number | string,
) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
Usage
var list = {
"one": { height: 100, weight: 15 },
"two": { height: 75, weight: 12 },
"three": { height: 116, weight: 9 },
"four": { height: 15, weight: 10 },
};
var sortedMap = sort(list, val => val.height);
The order of keys in a JavaScript object are not guaranteed, so I'm sorting and returning the result as a Map object which preserves the sort order.
If you want to convert it back to Object, you can do this:
var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });
const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]
const order = ['test2', 'test']
const setOrder = (arrayOfObjects, order) =>
arrayOfObjects.sort((a, b) => {
if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
return -1;
}
if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
return 1;
}
return 0;
});
my solution with sort :
let list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);
for(let element of sorted) {
console.log(element[0]+ ": " + element[1]);
}
A follow up answer to a long outdated question. I wrote two functions, one in which it sorts by keys, and the other by values, and returns the object in its sorted form in both functions. It should also work on strings as that is the reason why I am posting this (was having difficulty with some of the above on sorting by values if the values weren't numeric).
const a = {
absolutely: "works",
entirely: 'zen',
best: 'player',
average: 'joe'
}
const prop_sort = obj => {
return Object.keys(obj)
.sort()
.reduce((a, v) => {
a[v] = obj[v];
return a;
}, {});
}
const value_sort = obj => {
const ret = {}
Object.values(obj)
.sort()
.forEach(val => {
const key = Object.keys(obj).find(key => obj[key] == val)
ret[key] = val
})
return ret
}
console.log(prop_sort(a))
console.log(value_sort(a))
many similar and useful functions:
https://github.com/shimondoodkin/groupbyfunctions/
function sortobj(obj)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
function sortobjkey(obj,key)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
k=key; if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
Here is one more example:
function sortObject(obj) {
var arr = [];
var prop;
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) {
return a.value - b.value;
});
return arr; // returns array
}
var list = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
var arr = sortObject(list);
console.log(arr);

How to sort JavaScript object by its values? [duplicate]

If I have a JavaScript object such as:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
Is there a way to sort the properties based on value? So that I end up with
list = {
"bar": 15,
"me": 75,
"you": 100,
"foo": 116
};
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);
In ES10, you can use Object.fromEntries() to convert array to object. Then the code can be simplified to this:
const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
const sortable = Object.fromEntries(
Object.entries(maxSpeed).sort(([,a],[,b]) => a-b)
);
console.log(sortable);
We don't want to duplicate the entire data structure, or use an array where we need an associative array.
Here's another way to do the same thing as bonna:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted); // bar,me,you,foo
Your objects can have any amount of properties and you can choose to sort by whatever object property you want, number or string, if you put the objects in an array. Consider this array:
var arrayOfObjects = [
{
name: 'Diana',
born: 1373925600000, // Mon, Jul 15 2013
num: 4,
sex: 'female'
},
{
name: 'Beyonce',
born: 1366832953000, // Wed, Apr 24 2013
num: 2,
sex: 'female'
},
{
name: 'Albert',
born: 1370288700000, // Mon, Jun 3 2013
num: 3,
sex: 'male'
},
{
name: 'Doris',
born: 1354412087000, // Sat, Dec 1 2012
num: 1,
sex: 'female'
}
];
sort by date born, oldest first
// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
return a.born - b.born;
});
console.log('by date:');
console.log(byDate);
sort by name
var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
return x < y ? -1 : x > y ? 1 : 0;
});
console.log('by name:');
console.log(byName);
http://jsfiddle.net/xsM5s/16/
ECMAScript 2017 introduces Object.values / Object.entries. As the name suggests, the former aggregates all the values of an object into an array, and the latter does the whole object into an array of [key, value] arrays; Python's equivalent of dict.values() and dict.items().
The features make it pretty easier to sort any hash into an ordered object. As of now, only a small portion of JavaScript platforms support them, but you can try it on Firefox 47+.
EDIT: Now supported by all modern browsers!
let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]
let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]
For completeness sake, this function returns sorted array of object properties:
function sortObject(obj) {
var arr = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) { return a.value - b.value; });
//arr.sort(function(a, b) { return a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
return arr; // returns array
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]
JSFiddle with the code above is here. This solution is based on this article.
Updated fiddle for sorting strings is here. You can remove both additional .toLowerCase() conversions from it for case sensitive string comparation.
An "arrowed" version of #marcusR 's answer for reference
var myObj = { you: 100, me: 75, foo: 116, bar: 15 };
keysSorted = Object.keys(myObj).sort((a, b) => myObj[a] - myObj[b]);
alert(keysSorted); // bar,me,you,foo
UPDATE: April 2017
This returns a sorted myObj object defined above.
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result =
Object.keys(myObj)
.sort((a, b) => myObj[a] - myObj[b])
.reduce(
(_sortedObj, key) => ({
..._sortedObj,
[key]: myObj[key]
}),
{}
);
document.write(JSON.stringify(result));
UPDATE: March 2021 - Object.entries with sort function (updated as per comments)
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result = Object
.entries(myObj)
.sort((a, b) => a[1] - b[1])
.reduce((_sortedObj, [k,v]) => ({
..._sortedObj,
[k]: v
}), {})
document.write(JSON.stringify(result));
JavaScript objects are unordered by definition (see the ECMAScript Language
Specification, section 8.6). The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you need things to be ordered, use an array and the Array.prototype.sort method.
OK, as you may know, javascript has sort() function, to sort arrays, but nothing for object...
So in that case, we need to somehow get array of the keys and sort them, thats the reason the apis gives you objects in an array most of the time, because Array has more native functions to play with them than object literal, anyway, the quick solotion is using Object.key which return an array of the object keys, I create the ES6 function below which does the job for you, it uses native sort() and reduce() functions in javascript:
function sortObject(obj) {
return Object.keys(obj)
.sort().reduce((a, v) => {
a[v] = obj[v];
return a; }, {});
}
And now you can use it like this:
let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);
Check the sortedMyObject and you can see the result sorted by keys like this:
{a: 1, b: 2, c: 3, d: 4, e: 5}
Also this way, the main object won't be touched and we actually getting a new object.
I also create the image below, to make the function steps more clear, in case you need to change it a bit to work it your way:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
function sortAssocObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
// [["you",100],["me",75],["foo",116],["bar",15]]
sortable.sort(function(a, b) {
return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
});
// [["bar",15],["me",75],["you",100],["foo",116]]
var orderedList = {};
for (var idx in sortable) {
orderedList[sortable[idx][0]] = sortable[idx][1];
}
return orderedList;
}
sortAssocObject(list);
// {bar: 15, me: 75, you: 100, foo: 116}
Update with ES6: If your concern is having a sorted object to iterate through (which is why i'd imagine you want your object properties sorted), you can use the Map object.
You can insert your (key, value) pairs in sorted order and then doing a for..of loop will guarantee having them loop in the order you inserted them
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
// 0 = zero
// 1 = one
Sort values without multiple for-loops (to sort by the keys change index in the sort callback to "0")
const list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.fromEntries(
Object.entries(list).sort( (a,b) => a[1] - b[1] )
)
console.log('Sorted object: ', sorted)
Very short and simple!
var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
sortedList[key] = list[key]; });
Underscore.js or Lodash.js for advanced array or object sorts
var data = {
"models": {
"LTI": [
"TX"
],
"Carado": [
"A",
"T",
"A(пасс)",
"A(груз)",
"T(пасс)",
"T(груз)",
"A",
"T"
],
"SPARK": [
"SP110C 2",
"sp150r 18"
],
"Autobianchi": [
"A112"
]
}
};
var arr = [],
obj = {};
for (var i in data.models) {
arr.push([i, _.sortBy(data.models[i], function(el) {
return el;
})]);
}
arr = _.sortBy(arr, function(el) {
return el[0];
});
_.map(arr, function(el) {
return obj[el[0]] = el[1];
});
console.log(obj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js" integrity="sha256-qXBd/EfAdjOA2FGrGAG+b3YBn2tn5A6bhz+LSgYD96k=" crossorigin="anonymous"></script>
I am following the solution given by slebetman (go read it for all the details), but adjusted, since your object is non-nested.
// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
sort_array.push({key:key,value:list[key]});
}
// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});
// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
var item = list[sort_array[i].key];
// now do stuff with each item
}
let toSort = {a:2323, b: 14, c: 799}
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1])
Output:
[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]
There are many ways to do this, but since I didn't see any using reduce() I put it here. Maybe it seems utils to someone.
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let result = Object.keys(list).sort((a,b)=>list[a]>list[b]?1:-1).reduce((a,b)=> {a[b]=list[b]; return a},{});
console.log(result);
Thanks to #orad for providing the answer in TypeScript. Now, We can use the below codesnippet in JavaScript.
function sort(obj,valSelector) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
const Countries = { "AD": { "name": "Andorra", }, "AE": { "name": "United Arab Emirates", }, "IN": { "name": "India", }}
// Sort the object inside object.
var sortedMap = sort(Countries, val => val.name);
// Convert to object.
var sortedObj = {};
sortedMap.forEach((v,k) => { sortedObj[k] = v }); console.log(sortedObj);
//Output: {"AD": {"name": "Andorra"},"IN": {"name": "India"},"AE": {"name": "United Arab Emirates"}}
Sorting object property by values
const obj = { you: 100, me: 75, foo: 116, bar: 15 };
const keysSorted = Object.keys(obj).sort((a, b) => obj[a] - obj[b]);
const result = {};
keysSorted.forEach(key => { result[key] = obj[key]; });
document.write('Result: ' + JSON.stringify(result));
The desired output:
{"bar":15,"me":75,"you":100,"foo":116}
References:
Sorting object property by values
Convert array into object
This could be a simple way to handle it as a real ordered object. Not sure how slow it is. also might be better with a while loop.
Object.sortByKeys = function(myObj){
var keys = Object.keys(myObj)
keys.sort()
var sortedObject = Object()
for(i in keys){
key = keys[i]
sortedObject[key]=myObj[key]
}
return sortedObject
}
And then I found this invert function from:
http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/
Object.invert = function (obj) {
var new_obj = {};
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
new_obj[obj[prop]] = prop;
}
}
return new_obj;
};
So
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)
Just in case, someone is looking for keeping the object (with keys and values), using the code reference by #Markus R and #James Moran comment, just use:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
.map(key => newO[key] = list[key]);
console.log(newO); // {bar: 15, me: 75, you: 100, foo: 116}
<pre>
function sortObjectByVal(obj){
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
newObj[x] = obj[x];
}
return newObj;
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>
Object sorted by value (DESC)
function sortObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
sortable.sort(function(a, b) {
return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
});
var orderedList = {};
for (var i = 0; i < sortable.length; i++) {
orderedList[sortable[i][0]] = sortable[i][1];
}
return orderedList;
}
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
.sort((c,b) => {
return a[b]-a[c]
})
.reduce((acc, cur) => {
let o = {}
o[cur] = a[cur]
acc.push(o)
return acc
} , [])
output = [ { p: 8 }, { c: 2 }, { b: 1 }, { g: 1 } ]
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
tmpList[key] = list[key];
delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }
TypeScript
The following function sorts object by value or a property of the value. If you don't use TypeScript you can remove the type information to convert it to JavaScript.
/**
* Represents an associative array of a same type.
*/
interface Dictionary<T> {
[key: string]: T;
}
/**
* Sorts an object (dictionary) by value or property of value and returns
* the sorted result as a Map object to preserve the sort order.
*/
function sort<TValue>(
obj: Dictionary<TValue>,
valSelector: (val: TValue) => number | string,
) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
Usage
var list = {
"one": { height: 100, weight: 15 },
"two": { height: 75, weight: 12 },
"three": { height: 116, weight: 9 },
"four": { height: 15, weight: 10 },
};
var sortedMap = sort(list, val => val.height);
The order of keys in a JavaScript object are not guaranteed, so I'm sorting and returning the result as a Map object which preserves the sort order.
If you want to convert it back to Object, you can do this:
var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });
const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]
const order = ['test2', 'test']
const setOrder = (arrayOfObjects, order) =>
arrayOfObjects.sort((a, b) => {
if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
return -1;
}
if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
return 1;
}
return 0;
});
my solution with sort :
let list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);
for(let element of sorted) {
console.log(element[0]+ ": " + element[1]);
}
A follow up answer to a long outdated question. I wrote two functions, one in which it sorts by keys, and the other by values, and returns the object in its sorted form in both functions. It should also work on strings as that is the reason why I am posting this (was having difficulty with some of the above on sorting by values if the values weren't numeric).
const a = {
absolutely: "works",
entirely: 'zen',
best: 'player',
average: 'joe'
}
const prop_sort = obj => {
return Object.keys(obj)
.sort()
.reduce((a, v) => {
a[v] = obj[v];
return a;
}, {});
}
const value_sort = obj => {
const ret = {}
Object.values(obj)
.sort()
.forEach(val => {
const key = Object.keys(obj).find(key => obj[key] == val)
ret[key] = val
})
return ret
}
console.log(prop_sort(a))
console.log(value_sort(a))
many similar and useful functions:
https://github.com/shimondoodkin/groupbyfunctions/
function sortobj(obj)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
function sortobjkey(obj,key)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
k=key; if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
Here is one more example:
function sortObject(obj) {
var arr = [];
var prop;
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) {
return a.value - b.value;
});
return arr; // returns array
}
var list = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
var arr = sortObject(list);
console.log(arr);

Categories

Resources