Quick Tip: How to Sort an Array of Objects in JavaScript
If you need to sort an array of objects into a certain order, you might be tempted to reach for a JavaScript library. But before you do, remember that you can do some pretty neat sorting with the native Array.sort function.
In this article, we’ll show you how to sort an array of objects in JavaScript using strings, numbers, and dates. We’ll also give some great tips for dealing with case-sensitivity, copies of arrays, and popular libraries that handle all of this for you.
Basic Array Sorting (and why it doesn’t work)
By default, the JavaScript Array.sort
function converts each element in the array that needs to be sorted into a string, and compares them in Unicode code point order.
const foo = [9, 1, 4, 'zebroid', 'afterdeck'];
foo.sort(); // returns [ 1, 4, 9, 'afterdeck', 'zebroid' ]
const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }];
bar.sort(); // returns [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]
You may be wondering why 32 comes before 5. Not logical, huh? Well, actually it is. This happens because each element in the array is first converted to a string, and "32"
comes before "5"
in Unicode order.
Using Array.sort
alone wouldn’t be very useful for sorting an array of objects. Thankfully, the sort method takes an optional compareFunction
parameter, which we can use to sort our array of objects.
How to Sort an Array of Objects in JavaScript
To sort an array of objects, use the sort() method with a compare function. A compareFunction
applies rules to sort arrays by defined our own logic. They allow us to sort arrays of objects by strings, integers, dates, or any other custom property. We’ll cover the specifics of how compare functions work later in this article.
For this demo we’ll use an array of singers and sort them by their band names alphabetically:
const singers = [
{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },
{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },
{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
];
The following compare
function compares the (uppercase) name of each band:
function compare(a, b) {
// Use toUpperCase() to ignore character casing
const bandA = a.band.toUpperCase();
const bandB = b.band.toUpperCase();
let comparison = 0;
if (bandA > bandB) {
comparison = 1;
} else if (bandA < bandB) {
comparison = -1;
}
return comparison;
}
singers.sort(compare);
/* returns [
{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },
{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }
] */
To reverse the sorting order, you can invert the return value of the compare
function:
function compare(a, b) {
...
//invert return value by multiplying by -1
return comparison * -1;
}
How Compare Functions work
The compareFunction
returns a number which is used to determine the sorting order by comparing its two inputs (a
and b
). Quite simply, if the integer is less than 0, a
will appear before b
. If it’s greater than 0, b
will appear before a
. If it’s exactly 0, the original order is kept. However you determine that number is up to you.
Let’s look at a simple example with an array of numbers:
const nums = [79, 48, 12, 4];
function compare(a, b) {
if (a > b) return 1;
if (b > a) return -1;
return 0;
}
nums.sort(compare);
// => 4, 12, 48, 79
We can refactor this a little, as subtracting a
from b
will also give us the return value. This compare function sorts an array of numbers from smallest to largest:
function compareNums(a, b) {
return a - b;
}
nums.sort(compareNums)
It can also be represented as an arrow function without having to define the compare function elsewhere:
nums.sort((a, b) => a - b);
If you’re not familiar with arrow functions, you can read more about them here: Arrow Functions in JavaScript.
As you can see, the compare function can be written in a variety of ways and the sort()
method will act as instructed.
Creating a Dynamic Sorting Function
Let’s finish up our earlier example by making this more dynamic. Let’s create a sorting function, which you can use to sort an array of objects, whose values are either strings or numbers. This function has two parameters — the key we want to sort by and the order of the results (i.e. ascending or descending):
const singers = [
{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },
{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },
{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
];
function compareValues(key, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
// property doesn't exist on either object
return 0;
}
const varA = (typeof a[key] === 'string')
? a[key].toUpperCase() : a[key];
const varB = (typeof b[key] === 'string')
? b[key].toUpperCase() : b[key];
let comparison = 0;
if (varA > varB) {
comparison = 1;
} else if (varA < varB) {
comparison = -1;
}
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
}
And this is how you’d use it:
// array is sorted by band, in ascending order by default
singers.sort(compareValues('band'));
// array is sorted by band in descending order
singers.sort(compareValues('band', 'desc'));
// array is sorted by name in ascending order
singers.sort(compareValues('name'));
// array is sorted by date if birth in descending order
singers.sort(compareValues('born', 'desc'));
In the code above, the hasOwnProperty method is used to check if the specified property is defined on each object and has not been inherited via the prototype chain. If it’s not defined on both objects, the function returns 0
, which causes the sort order to remain as is (i.e. the objects remain unchanged with respect to each other).
The typeof operator is also used to check the data type of the property’s value. This allows the function to determine the proper way to sort the array. For example, if the value of the specified property is a string
, a toUpperCase
method is used to convert all its characters to uppercase, so character casing is ignored when sorting.
You can adjust the above function to accommodate other data types, and any other needs your script may have.
Popular Libraries for Sorting Arrays
You may not have the time or patience to create your own sorting functions in vanilla JavaScript. Time is money and code takes time. Luckily there are a variety of libraries that cater to all your array sorting needs. Here’s a short list of helper libraries that contain sorting functions… in no particular order ;)
Quick Tip: Sort an Array Of Objects by Date
To sort an array of objects by date strings all you have to do is provide a compare function that parses the date string first and subtract them from each other:
const singers = [
{ name: 'Steven Tyler', band: 'Aerosmith', birthdate: 'March 26 1948' },
{ name: 'Karen Carpenter', band: 'The Carpenters', birthdate: 'March 2 1950' },
...
];
function compareDates(a, b) {
return Date.parse(new Date(a.birthdate)) - Date.parse(new Date(b.birthdate))
}
Quick tip: Sort an Array without Modifying it
Unlike many other JavaScript array functions, Array.sort
is one of the methods that mutate (change) the array it sorts instead of returning a new array. To avoid this, you can create a new instance of the array to be sorted and modify that instead. This is possible using an array method or the spread syntax to create a copy of the array.
const baz = ['My cat ate my homework', 37, 9, 5, 17];
baz.sort(); // baz array is modified
console.log(baz); // shows [ 17, 37, 5, 9, 'My cat ate my homework' ]
Using Array.slice to create a copy of the array:
const sortedBaz = baz.slice().sort();
// a new instance of the baz array is created and sorted
Alternatively you can use the spread operator for the same effect:
const sortedBaz = [...baz].sort();
// a new instance of the baz array is created and sorted
The output is the same in both cases and can be used before sorting any array of objects.
console.log(baz); // ['My cat ate my homework', 37, 9, 5, 17];
console.log(sortedBaz); // [ 17, 37, 5, 9, 'My cat ate my homework' ]
Quick tip: A Case-Insensitive Way to Sort Arrays by Strings
In our earlier example, we wanted to sort an array of objects, whose values are either strings or numbers. If, however, you know that you’ll only be dealing with objects whose values are strings, you can tidy up the code a little using JavaScript’s localeCompare
method.
This method returns a number indicating whether a string comes before, after, or is the same as a given string in the sort order. It enables a case-insensitive sort of an array:
['bjork', 'Bjork', 'Björk'].sort();
// [ 'Bjork', 'Björk', 'bjork' ]
['bjork', 'Bjork', 'Björk'].sort((a, b) => a.localeCompare(b));
// [ 'bjork', 'Bjork', 'Björk' ]
In terms of our compareValues
function, that means we could write:
function compareValues(key, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) return 0;
const comparison = a[key].localeCompare(b[key]);
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
}
You can read more about localeCompare over on MDN.
Conclusion
So there you have it — a short introduction to sorting an array of objects using vanilla JavaScript. Although many libraries offer this kind of dynamic sorting ability, as demonstrated, it’s not all that hard to implement this functionality yourself. Plus it’s good to understand what is going on under the hood.
To build the most comprehensive understanding of native JavaScript’s foundations, we recommend JavaScript: Novice to Ninja. Learn JavaScript, including ES6, from the ground up and put your new knowledge into practice by building along with a range of projects.
FAQs on how to sort an array of objects in JavaScript
Yes. JavaScript provides built-in methods to help sort array elements.
You can sort an array of objects in JavaScript by using the Array.prototype.sort()
method and providing a custom comparison function. The comparison function should compare the relevant property of each object.
You can dynamically sort an array of objects based on different keys by providing the key to the comparison function. This allows you to sort by various properties. To sort an array of objects by a specific key (property) in JavaScript, you can use the Array.prototype.sort()
method along with a custom comparison function that compares the values of the desired key for each object.
To dynamically sort an array of objects in JavaScript based on a key (property) that is determined at runtime, you can create a function that accepts the array and the key as parameters. This function can then use the Array.prototype.sort()
method with a custom comparison function that accesses the dynamically provided key for sorting.
Yes, libraries like Lodash and Underscore.js provide utility functions for sorting arrays of objects with added features and convenience. However, JavaScript’s built-in sort()
method is often sufficient for basic sorting needs.
Yes, by default, sorting by object keys is case-sensitive. You can use the localeCompare()
method to perform case-insensitive sorting.