Skip to content

Instantly share code, notes, and snippets.

@umidjons
Last active January 16, 2024 13:00
Show Gist options
  • Star 67 You must be signed in to star a gist
  • Fork 22 You must be signed in to fork a gist
  • Save umidjons/9614157 to your computer and use it in GitHub Desktop.
Save umidjons/9614157 to your computer and use it in GitHub Desktop.
JavaScript: sort object properties by value (numeric or string)

Sort object properties by value (values are text)

I have following object:

var cities={10:'Tashkent', 14:'Karakalpakiya', 16:'Andijan'};

I want sort it by city names, so after sort it should be:

var cities={16:'Andijan', 14:'Karakalpakiya', 10:'Tashkent'};

But I can't sort object properties, instead can convert object into array, then sort items.

function sortProperties(obj)
{
  // convert object into array
	var sortable=[];
	for(var key in obj)
		if(obj.hasOwnProperty(key))
			sortable.push([key, obj[key]]); // each item is an array in format [key, value]
	
	// sort items by value
	sortable.sort(function(a, b)
	{
		var x=a[1].toLowerCase(),
			y=b[1].toLowerCase();
		return x<y ? -1 : x>y ? 1 : 0;
	});
	return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ]
}

Example:

var sortedCities=sortProperties(cities);
console.log(sortedCities); // [[16, 'Andijan'], [14, 'Karakalpakiya'], [10, 'Tashkent']]

Sort object properties by value (values are numbers)

I have following object:

var cities={Tashkent:447, Karakalpakiya:900, Andijan:120};

I want sort it by city rating, so after sort it should be:

var cities={Andijan:120, Tashkent:447, Karakalpakiya:900};

But again I can't sort object properties, instead can convert object into array, then sort items.

function sortProperties(obj)
{
  // convert object into array
	var sortable=[];
	for(var key in obj)
		if(obj.hasOwnProperty(key))
			sortable.push([key, obj[key]]); // each item is an array in format [key, value]
	
	// sort items by value
	sortable.sort(function(a, b)
	{
	  return a[1]-b[1]; // compare numbers
	});
	return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ]
}

Example:

var sortedCities=sortProperties(cities);
console.log(sortedCities); // [[Andijan, 120], [Tashkent, 447], [Karakalpakiya, 900]]

###Improved version with additional parameter to set sort type (numeric or text)

/**
 * Sort object properties (only own properties will be sorted).
 * @param {object} obj object to sort properties
 * @param {bool} isNumericSort true - sort object properties as numeric value, false - sort as string value.
 * @returns {Array} array of items in [[key,value],[key,value],...] format.
 */
function sortProperties(obj, isNumericSort)
{
	isNumericSort=isNumericSort || false; // by default text sort
	var sortable=[];
	for(var key in obj)
		if(obj.hasOwnProperty(key))
			sortable.push([key, obj[key]]);
	if(isNumericSort)
		sortable.sort(function(a, b)
		{
			return a[1]-b[1];
		});
	else
		sortable.sort(function(a, b)
		{
			var x=a[1].toLowerCase(),
				y=b[1].toLowerCase();
			return x<y ? -1 : x>y ? 1 : 0;
		});
	return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ]
}
@osk2
Copy link

osk2 commented Oct 8, 2015

Thanks, this helps me a lot 👍

@kl3sk
Copy link

kl3sk commented May 11, 2016

Thanks for your function, but i need to sort a structured object, so i update your function like this.

        /**
         * Sort object properties (only own properties will be sorted).
         * @param {object} obj object to sort properties
         * @param {string|int} sortedBy 1 - sort object properties by specific value.
         * @param {bool} isNumericSort true - sort object properties as numeric value, false - sort as string value.
         * @param {bool} reverse false - reverse sorting.
         * @returns {Array} array of items in [[key,value],[key,value],...] format.
         */
        function sortProperties(obj, sortedBy, isNumericSort, reverse) {
            sortedBy = sortedBy || 1; // by default first key
            isNumericSort = isNumericSort || false; // by default text sort
            reverse = reverse || false; // by default no reverse

            var reversed = (reverse) ? -1 : 1;

            var sortable = [];
            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    sortable.push([key, obj[key]]);
                }
            }
            if (isNumericSort)
                sortable.sort(function (a, b) {
                    return reversed * (a[1][sortedBy] - b[1][sortedBy]);
                });
            else
                sortable.sort(function (a, b) {
                    var x = a[1][sortedBy].toLowerCase(),
                        y = b[1][sortedBy].toLowerCase();
                    return x < y ? reversed * -1 : x > y ? reversed : 0;
                });
            return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ]
        }

Exemple :

            var cities = {
                'first city': {
                    name: 'First City',
                    sort: 10
                },
                'second city': {
                    name: 'Second City',
                    sort: 14
                },
                'third city': {
                    name: 'Third City',
                    sort: 20
                },
                'fourth city': {
                    name: 'Fourth City',
                    sort: 2
                }
            };
            sortProperties(cities, 'sort', true, false);

@ForgeableSum
Copy link

Neat function. And if you need to convert that array back into an object, simply do this:

function sortObjects(objects) {

    var newObject = {};

    var sortedArray = sortProperties(objects, 'zindex', true, false);
    for (var i = 0; i < sortedArray.length; i++) {
        var key = sortedArray[i][0];
        var value = sortedArray[i][1];

        newObject[key] = value;

    }

    return newObject;

}

@RejinR
Copy link

RejinR commented Dec 27, 2016

Thanks... This helped me a lot.. 😄

@pufinek
Copy link

pufinek commented Feb 9, 2017

Great, thx, very helpful

@giffeler
Copy link

giffeler commented Jul 6, 2017

Convert the object into an array using yourArray = Object.entries(yourObject). Afterwards use Array.sort with your own sorting function e.g. yourArray.sort((x, y) => y[0] - x[0]);

@budhapirthi
Copy link

awesome thanks

@fonini
Copy link

fonini commented Mar 21, 2018

Thanks, @kl3sk

@medusiora
Copy link

Thanks.

@jgorene
Copy link

jgorene commented May 14, 2018

Many thanks!

@MarksASP95
Copy link

I have to make an indexing project, you are heaven sent.

@wmrsp
Copy link

wmrsp commented Jul 31, 2018

Thanks mate! Still think it's ridiculous that javascript does not know associative arrays. It feels like such a waste having to iterate through, in my case, an api output containing id's and value's only and saving them in a javascript object only to iterate through them again because the javascript object is now sorted by key, and I need to present the user with an alphabetical list of values, with no way to sort by value. This all coming from a, currently, frustrated php developer. Cheers :).

@sudhir600
Copy link

@ForgeableSum
once sortProperties called. i am getting object as reverse order but when i called your function sortObjects, it again reset the object from ascending to descending. how to get back JSON object in same reformat.

Before sortObject (which give result as i want) [8, 5, 3, 1] correct in reverse order
image

But, See, what i am getting after sortObject [1, 3, 5, 8] worng in reverse order

image

@rodrigoespinozadev
Copy link

rodrigoespinozadev commented Jan 25, 2019

Thanks for your function, but i need to sort a structured object, so i update your function like this.

        /**
         * Sort object properties (only own properties will be sorted).
         * @param {object} obj object to sort properties
         * @param {string|int} sortedBy 1 - sort object properties by specific value.
         * @param {bool} isNumericSort true - sort object properties as numeric value, false - sort as string value.
         * @param {bool} reverse false - reverse sorting.
         * @returns {Array} array of items in [[key,value],[key,value],...] format.
         */
        function sortProperties(obj, sortedBy, isNumericSort, reverse) {
            sortedBy = sortedBy || 1; // by default first key
            isNumericSort = isNumericSort || false; // by default text sort
            reverse = reverse || false; // by default no reverse

            var reversed = (reverse) ? -1 : 1;

            var sortable = [];
            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    sortable.push([key, obj[key]]);
                }
            }
            if (isNumericSort)
                sortable.sort(function (a, b) {
                    return reversed * (a[1][sortedBy] - b[1][sortedBy]);
                });
            else
                sortable.sort(function (a, b) {
                    var x = a[1][sortedBy].toLowerCase(),
                        y = b[1][sortedBy].toLowerCase();
                    return x < y ? reversed * -1 : x > y ? reversed : 0;
                });
            return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ]
        }

Exemple :

            var cities = {
                'first city': {
                    name: 'First City',
                    sort: 10
                },
                'second city': {
                    name: 'Second City',
                    sort: 14
                },
                'third city': {
                    name: 'Third City',
                    sort: 20
                },
                'fourth city': {
                    name: 'Fourth City',
                    sort: 2
                }
            };
            sortProperties(cities, 'sort', true, false);

Thanks @ @kl3sk this helped me a lot!

@0zkr1
Copy link

0zkr1 commented Oct 4, 2019

@ForgeableSum: You can also do:
newObject = sortedArray.reduce( (obj, ent) => { obj[ ent[0] ] = ent[1]; return obj; }, /** @type {Any} */({}) );

@kl3sk
Copy link

kl3sk commented Oct 28, 2019

@sudhir600 this is because chrome/firefox console re sort them naturally. Use JSON.stringify and see that is sorted as you wish

@andres-paris
Copy link

Thanks a lot! It works perfectly for me.

@macyhvt
Copy link

macyhvt commented Jan 16, 2024

Saw this from one of colleagues comment and thanks for the great help. Cheers !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment