A compare function should be provided when using “Array.prototype.sort()”

The default sort order is alphabetic, rather than numeric, regardless of the types in the array. Specifically, even if an array contains only numbers, all values in it will be converted to strings and sorted lexicographically, for an order like this: 1, 15, 2, 20, 5.

Even to sort strings, the default sort order may give unexpected results. Not only does it not support localization, it also doesn’t fully support Unicode, as it only considers UTF-16 code units. For example, in the code below, "eΔ" is surprisingly before and after "éΔ".

const name1 = '\u00e9\u0394'; // "éΔ"
const name2 = '\u0065\u0301\u0394'; // "éΔ" using Unicode combining marks
const name3 = '\u0065\u0394'; // "eΔ"
console.log([name1, name2, name3].sort()); // ["éΔ", "eΔ", "éΔ"], "eΔ" position is inconsistent
console.log([name1, name2, name3].sort((a, b) => a.localeCompare(b))); // ["eΔ", "éΔ", "éΔ"]

Fortunately the sort method allows you to pass an optional compare function to specify the sort order. When a compare function is supplied, the returned order depends on the return value of the compare function.

Noncompliant Code Example

var myarray = [80, 3, 9, 34, 23, 5, 1];

myarray.sort();
console.log(myarray); // outputs: [1, 23, 3, 34, 5, 80, 9]

Compliant Solution

var myarray = [80, 3, 9, 34, 23, 5, 1];

myarray.sort((a, b) => (a - b));
console.log(myarray); // outputs: [1, 3,  5, 9, 23, 34, 80]

Leave a comment

Your email address will not be published. Required fields are marked *