Skip to main content Accessibility Feedback

Sorting an array by multiple criteria with vanilla JavaScript

Last week, my friend Andrew Borstein was playing around with a JavaScript upvoting system, and asked:

I want to sort an array based on two properties. First sort by an integer, next sort by a string. So an array of objects might look like this:

[
	{ title: 'Apple', votes: 1 },
	{ title: 'Milk', votes: 2 },
	{ title: 'Carrot', votes: 3 },
	{ title: 'Banana', votes: 2 }
]

and then be sorted into this

[
	{ title: 'Carrot', votes: 3 },
	{ title: 'Banana', votes: 2 },
	{ title: 'Milk', votes: 2 },
	{ title: 'Apple', votes: 1 }
]

In other words, show the item with the most votes first, and then for items with the same number of votes, sort alphabetically.

Using Array.sort()

The Array.sort() method let’s you compare items in an array and sort them.

To use it, you pass in a callback function that accepts two arguments. The first is the first item of the two it should compare, and the second is the second. You can name them anything you want.

var votes = [
	{ title: 'Apple', votes: 1 },
	{ title: 'Milk', votes: 2 },
	{ title: 'Carrot', votes: 3 },
	{ title: 'Banana', votes: 2 }
];

votes.sort(function (vote1, vote2) {
	console.log(vote1);
	console.log(vote2);
});

// Logs this to the console...
// {title: "Apple", votes: 1}
// {title: "Milk", votes: 2}
// {title: "Milk", votes: 2}
// {title: "Carrot", votes: 3}
// {title: "Carrot", votes: 3}
// {title: "Banana", votes: 2}

Array.sort() works by looping through each item in the array and comparing it to the one after it based on some criteria you specify in your comparison function.

If you return -1, it will place the first item before the second. If you return 1, it will place the second item before the first. If you return 0, it will leave them unchanged.

Sorting our votes

Let’s put Array.sort() into action.

First, we want to sort by the number of votes. We’ll compare each items number of votes (the vote property), and put the one with the most votes first.

votes.sort(function (vote1, vote2) {

	// Sort by votes
	// If the first item has a higher number, move it down
	// If the first item has a lower number, move it up
	if (vote1.votes > vote2.votes) return -1;
	if (vote1.votes < vote2.votes) return 1;

});

The votes array looks like this now.

[
	{title: "Carrot", votes: 3},
	{title: "Milk", votes: 2},
	{title: "Banana", votes: 2},
	{title: "Apple", votes: 1}
]

The items are sorted by votes, but not alphabetically yet. For example, Banana comes after Milk.

Right now, if vote1 and vote2 are the same, we do nothing and the order doesn’t change. Let’s instead then compare the title property, and move items that come first in the alphabet up.

With Array.sort(), if the letter comes later in the alphabet, it has a higher value than if it comes earlier.

votes.sort(function (vote1, vote2) {

	// Sort by votes
	// If the first item has a higher number, move it down
	// If the first item has a lower number, move it up
	if (vote1.votes > vote2.votes) return -1;
	if (vote1.votes < vote2.votes) return 1;

	// If the votes number is the same between both items, sort alphabetically
	// If the first item comes first in the alphabet, move it up
	// Otherwise move it down
	if (vote1.title > vote2.title) return 1;
	if (vote1.title < vote2.title) return -1;

});

If you refresh your browser and try sorting again, the votes array will now look like this.

[

	{title: "Carrot", votes: 3},
	{title: "Banana", votes: 2},
	{title: "Milk", votes: 2},
	{title: "Apple", votes: 1}
]

Extending this for your own needs

You can change the criteria your sorting against to match the properties of whatever array you’re working with. You can also change what value you return to switch the sorting order.

For example, if you wanted to return items with the fewest votes first, you’d switch which returns 1 and which returns -1.

votes.sort(function (vote1, vote2) {

	// Sort by votes
	// If the first item has a higher number, move it down
	// If the first item has a lower number, move it up
	if (vote1.votes > vote2.votes) return 1;
	if (vote1.votes < vote2.votes) return -1;

	// If the votes number is the same between both items, sort alphabetically
	// If the first item comes first in the alphabet, move it up
	// Otherwise move it down
	if (vote1.title > vote2.title) return 1;
	if (vote1.title < vote2.title) return -1;

});

You can also sort by additional criteria. If you had an array of objects with more than two properties, you could, for example, sort by a third criteria if the title property was the same between two items (maybe location or year).