The functionality of JavaScript arrays allows you to dynamically change their contents. For example, an array can be filled with elements, received as the results of functions execution. Also they can be replaced, deleted and modified during script execution.
Despite the built-in ability to skip and remove some indexes, as a rule, arrays are filled sequentially (cell by cell). But when you store a large amount of data you may need to sort array elements in a certain order.
In most cases, the standard (for Arrays) Array.prototype.sort()
method is suitable for ordering arrays elements in JavaScript. In default state, it works best with strings, but it can also be configured to order numbers and Objects in ascending or descending order. Also, its syntax allows you to set your own sorting algorithms.
How does the sort() method work?
The sort() method arranges elements in alphabetical order or according to specified comparison rules. It changes the original array during execution, keeping the elements that exist in it, but changing their indices (order). The sorting algorithm, which uses the sort()
method by default, can be supplemented by your own function, which will be called the Comparison function.
If you use it without additional parameters, all data in the target array will be read as string values. If there are multiple elements with the same first character, their second characters will be compared to determine their order, and so on. The elements will be sorted alphabetically, first with special characters, then with numbers and letters.
Order of characters will be determined according to their codes in UTF-16. This is one of the character encoding standards that interprets symbols in a comfortable (for humans) display. For example, uppercase "A" is denoted as /u0041
in it, while lowercase "a" will be /u0064
, etc. In total, this standard contains more than a million various symbols and letters of various alphabets. This allows you to sort textual information in almost any language.
But for the same reason, this method specifically sorts the numeric values. Describing numbers as string values, the method sorts them according to the order of their codes in UTF-16, ignoring mathematical rules. So if you use sort()
without parameters, it will put 215 higher than 2050, 210 lower than 22, and so on.
One of the main advantages of the sort()
method is the ability to specify additional sorting conditions for it. They must be defined inside the Compare function, which can be declared in 3 different ways. This function allows including to the sorting process additional variables, some properties of the elements and other parts of the script. You must use the Compare function for sorting numbers by value in the correct way.
Syntax
The sort method can take one optional parameter:
compareFunction
(a.k.a. comparator) - an optional parameter that can be used to set custom comparison rules for sorting.
Callback function will be called for each comparison. There are two arguments available inside function:
firstElement
- the first element taken for comparison (with SecondElement).secondElement
- the second element taken for comparison (with FirstElement).
Typically, firstElement
and secondElement
are used as part of the compareFunction
. The syntax of the sort()
method allows to declare it without parameters:
arrayName.sort([compareFunction]);
In such a case, all elements in arrayName
will be read as string values and sorted alphabetically, ignoring mathematical rules for numbers. The syntax of the sort()
method may differ depending on the selected way of setting the Compare function. Let's consider it, using the algorithm for sorting numbers according to mathematical rules:
Compare function via callback function
let numbers = [50, 6, 43, 71, 58, 46, 92, 36];
numbers.sort(compFunc);
function compFunc(a, b) {
return a - b;
}
In cases with callback functions we can use only the compFunc
parameter to refer to the function where we have implemented our own comparison algorithm.
Compare function via inline function
let numbers = [50, 6, 43, 71, 58, 46, 92, 36];
numbers.sort(function(a, b){return a - b});
Compare function via arrow function
let numbers = [50, 6, 43, 71, 58, 46, 92, 36];
numbers.sort((a, b) => a - b);
Compare functions supplement the sort()
algorithm, so it determines the order of numbers by comparing them with each other and putting them in ascending order. To arrange them in descending order, all you have to do is swap b and a in the return value.
The numbers will be sorted in ascending order this way:
return a - b;
The numbers will be sorted in descending order this way:
return b - a;
If you use arrays whose elements are Objects, you must consider the types of data stored in them. You also need to specify what data will be used for comparison. For example, we have an array where country is a string value and place is a numeric value:
let countries = [
{country: 'Peru', place: 43},
{country: 'Canada', place: 71},
{country: 'Italy', place: 58},
{country: 'Germany', place: 46},
{country: 'Japan', place: 92},
{country: 'Morocco', place: 36}
];
In such case, the Compare function syntax for sorting in ascending order based on the string value of country would be:
function compFunc(a, b){
if (a.country.toLowerCase() < b.country.toLowerCase()) {
return -1;
}
if (a.country.toLowerCase() > b.country.toLowerCase()) {
return 1;
}
return 0;
}
console.log(countries);
Result:
[ { country: 'Canada', place: 71 },
{ country: 'Germany', place: 46 },
{ country: 'Italy', place: 58 },
{ country: 'Japan', place: 92 },
{ country: 'Morocco', place: 36 },
{ country: 'Peru', place: 43 } ]
We need more complex algorithms for values in such arrays. In our example, it contains three parts and returns different values, depending on the result of comparing the two elements. If they are equal, the sort()
method returns 0, both here and in the default algorithm, and the elements remain unchanged.
Also, as in UTF-16, large and small letters are different characters with different codes, you need to convert your elements (in the Compare function) to a single format. This can be done by adding the toLowerCase()
or toUpperCase()
methods, which will convert all characters to the same form, keeping the original values without changes.
Test yourself
Task 1. Sort the array elements alphabetically. Print to the console the array values before and after sorting.
let words = ['*', 'year', 'winter', '', 'road', 4, 7, 'spring', 134, ' ', '. ',];
Solution. The sort()
method replaces the original array during execution, so we need to print its elements to the console in advance. After that, we can perform a standard (without parameters) sorting.
let words = ['*', 'year', 'winter', '', 'road', 4, 7, 'spring', 134, ' ', '. ',];
console.log(words);
words.sort();
console.log (words);
Result:
[ '*', 'year', 'winter', '', 'road', 4, 7, 'spring', 134, ' ', '. ' ]
[ '', ' ', '*', '. ', 134, 4, 7, 'road', 'spring', 'winter', 'year' ]
Task 2. Sort the elements of a numeric array in descending order using the inline function. Print the values of the resulting array to the console. Optimise the number of lines of code if possible.
let numbers = [12, 7, 12, 71, 55, 74, 73, 47, 35, 54];
Solution:
let numbers = [12, 7, 12, 71, 55, 74, 73, 47, 35, 54];
The usual solution to this problem will look like:
let numbers = [12, 7, 12, 71, 55, 74, 73, 47, 35, 54];
numbers.sort(function(a, b){return b - a});
console.log(numbers);
But we can optimise the code by reducing the number of lines. Then the full solution would be:
let numbers = [12, 7, 12, 71, 55, 74, 73, 47, 35, 54];
console.log(numbers.sort(function(a, b){return b - a}));
Task 3. Sort an array of string elements alphabetically using the
sort()
method. If necessary, you can use callback functions.
let vegetables = ['cABBAge', 'Broccoli', 'PepPer', 'lettuce', 'garlic', 'TOMATO', 'Celery', 'onion', 'Potato'];
Solution. The array elements use the Upper and Lower cases, so we will create a callback function to set our own sorting algorithm. Inside it, we will use the toLowerCase()
method, which is important for correct sorting in such cases.
let vegetables = ['cABBAge', 'Broccoli', 'PepPer', 'lettuce', 'garlic', 'TOMATO', 'Celery', 'onion', 'Potato'];
function compFunc(a, b) {
if ( a.toLowerCase() < b.toLowerCase() ) {
return -1;
} else if ( a.toLowerCase() > b.toLowerCase() ) {
return 1;
} else {
return 0;
}
}
console.log(vegetables.sort(compFunc));
Result:
[ 'Broccoli',
'cABBAge',
'Celery',
'garlic',
'lettuce',
'onion',
'PepPer',
'Potato',
'TOMATO' ]
Note that it also can be solved using the toUpperCase()
method instead of toLowerCase()
. In this case, it will not affect the final result.