0

I can sort the array [1, 3, 2] by calling the .sort() method on it. Optionally, I can pass in a comparison function to do things like sorting the array in reverse. This always works when the array contains Numbers.

However, when the array contains Strings, the .sort() method is unpredictable. It will sort the array if no optional comparison function is provided, but will not sort if a comparison function is provided.

Why does this happen? Is there a workaround?

I have included a code snippet below that illustrates the problem.

let letters;
let numbers;

letters = ["a", "c", "b"];
numbers = [1, 3, 2];
console.log(letters.sort());                  // ["a", "b", "c"] DOES SORT
console.log(numbers.sort());                  // [1, 2, 3].      DOES SORT

letters = ["a", "c", "b"];
numbers = [1, 3, 2];
console.log(letters.sort((a, b) => a - b));   // ["a", "c", "b"] DOES NOT SORT
console.log(numbers.sort((a, b) => a - b));   // [1, 2, 3]       DOES SORT

letters = ["a", "c", "b"];
numbers = [1, 3, 2];
console.log(letters.sort((a, b) => b - a));   // ["a", "c", "b"] DOES NOT SORT
console.log(numbers.sort((a, b) => b - a));   // [3, 2, 1]       DOES SORT

4
  • 4
    What do you think subtraction means with strings? Commented Feb 3, 2021 at 17:33
  • 2
    numbers.sort() does not work. Try [2, 10]. Commented Feb 3, 2021 at 17:34
  • 1
    “Is there a workaround?” — Read the documentation; use localeCompare. Commented Feb 3, 2021 at 17:36
  • 2
    Have you read the description of what the comparison function is supposed to return? Commented Feb 3, 2021 at 17:36

3 Answers 3

1

Because "a" - "b" == NaN.

From Array.sort docs:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -1;
  }
  if (a is greater than b by the ordering criterion) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

Array.sort() expects the compare function to return a numerical value.

Sign up to request clarification or add additional context in comments.

Comments

1

I would encourage you to read the documentation on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Array sort is a weird one, but the gist of it is that the "compare function" (which is the thing you pass to sort() ie. (a, b) => a - b)) has to return a number. You can easily test it in the browser console, and you'll see that subtracting two strings doesn't work 'a' - 'b'.

As a workaround you can use localeCompare (also mentioned in the docs).

var letters = ["a", "c", "b"];
letters.sort(function (a, b) {
  return a.localeCompare(b);
});

Comments

1

"When sort() is called without arguments, the array items are transformed into strings and sorted. invoking the method on numbers performs the same alphabetical sorting:"

Not mine, though

https://dmitripavlutin.com/javascript-array-sort-numbers/.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.