sajad torkamani

The default comparison function (lexicographical order)

The Array.prototype.sort() method sorts the elements of an array and returns the sorted array. By default (without any arguments), it sorts in ascending order, by converting each element into a string, and comparing the UTF-16 code of each character. This is sometimes referred to as lexicographic ordering.

const months = ['January', 'February', 'March', 'April']
console.log(months.sort())
// [ 'April', 'February', 'January', 'March' ]

const numbers = [4, 2, 6, 10, 8, 13]
console.log(numbers.sort())
// [10, 13, 2, 4, 6, 8]

13 is sorted before 2, 4, 6, and 8, because its first character (1), has a smaller UTF-16 code than the others.

How to use a custom comparison function

The sort method takes an optional comparison function that lets you sort elements using custom logic.

This function must return an integer where each integer determines how the two elements being compared are to be sorted.

compareFunction(a, b) return valuesort order
< 0sort a before b
> 0sort a after b
=== 0keep original order of a and b

Here’s an example comparison function that sorts an array by placing the shortest words as the start (repl):

function sortByLengthAsc(a, b) {
  if (a.length === b.length) {
    // If the lengths are the same, keep original order.
    return 0
  }

  if (a.length < b.length) {
    // If a is shorter than b, put it before b.
    // We want the shortest words to appear first.
    return -1
  }

  // Put b after a
  return 1
}

const sortedAscResult = ['Bob', 'Jimmy', 'Michelangelo', 'Mo'].sort(sortByLengthAsc)
console.log('Sorted by length (ASC):', sortedAscResult)
// Sorted by length (ASC): [ 'Mo', 'Bob', 'Jimmy', 'Michelangelo' ]

What about other values like null, undefined, false, etc?

undefined elements are sorted to the end of the array:

[undefined, 'alice', 'bob', 'zarah'].sort()
// ['alice', 'bob', 'zarah', undefined]

Everything else is converted to a string (seemingly using the String() constructor. For example:

// null values
[null, 'alice', 'bob', 'zarah'].sort()
// ['alice', 'bob', null, 'zarah']

// false values
[false, 'alice', 'bob', 'zarah'].sort()
['alice', 'bob', false, 'zarah']

// NaN values
['NaN', 'alice', 'NaM', 'bob', 'zarah'].sort()
// ['NaN', 'NaN', 'alice', 'bob', 'zarah'] // Capital letters are sorted before lowercase letters

In each case, you get the same result as if you passed the string equivalent (e.g., "null" instead of null or "false" instead of false).

Sources

Tagged: JavaScript