Anonymous arrow function sorting array

This a task from a JS workshop I am working on:

let numbers = [50, 10, 40, 30, 20];
function compareNumbers(a, b) {
    let retVal = 0;
    if (a < b) {
        retVal = -1;
    } else if(a > b) {
        retVal = 1;
    }
    return retVal;
}
let sorted = numbers.sort(compareNumbers);
console.log(sorted); // [10, 20, 30, 40, 50]

I am asked to do the following:

A. Try to modify the above piece of code to make it as short as possible. Suggestions:

  • use an anonymous function;
  • use an arrow function;
  • consider skipping the if statement.

This is not an exercise from freeCodeCamp and it is not a homework or a test from elsewhere. Anyway, I did this:

let numbers = [50, 10, 40, 30, 20];
let fix = (a, b) => (a < b)? retVal = -1 : ((a > b)? retVal = 1 : 0)
let sorted = numbers.sort(fix);
console.log(sorted);

But upon looking at the solution for this task this is what’s offered:

let numbers = [50, 10, 40, 30, 20];
let sorted = numbers.sort((a, b) => a - b);
console.log(sorted);

I frankly don’t get it… I don’t understand the answer nor, like most of the time, I don’t know what am I doing here…

If anyone could offer me an explanation I would appreciate it.

The return value for the sorter is

  • -1 or any number < 0 (latter treated as -1),
  • 0,
  • or 1 or any number > 0 (latter treated as 1)

Then it sorts by comparing two values at a time (a and b). As long as those are numbers (or are/can be converted to numbers), then

function compareNumbers(a, b) {
  return a - b;
}

Is in practice exactly the same as

function compareNumbers(a, b) {
    let retVal = 0;
    if (a < b) {
        retVal = -1;
    } else if(a > b) {
        retVal = 1;
    }
    return retVal;
}
1 Like

Many many thanks. So the function walks through the array comparing pairs like this:

let numbers = [50, 10, 40, 30, 20];
let sorted = numbers.sort((a, b) => a - b);
console.log(sorted);

At first it would compare a=50 with b=10. Since the function results in a positive value, will it flip the first two components of the array so as to become:

[10, 50, 40, 30, 20]

Then, will it grab a=50 and b=40 and do the same and so on, untile the array is sorted?

1 Like

Exactly right.

Keep in mind that for array string values .sort() uses unicode character references, so “50” would be sorted before “6” so the string values should be converted to numbers before using the .sort() method.

Very nice of you to answer. Much obliged! :smiley:

As an aside: If you do end up needing to sort alphabetically, then there is a function provided for this, localeCompare, which handles it properly, in a locale-aware manner. So assuming English locale:

const words = "Hello this needs to be sorted because Reasons".split(" ");

const sortedWords = words.sort((a, b) => a.localeCompare(b));

console.log(sortedWords);
// ["be", "because", "Hello", "needs", "Reasons", "sorted", "this", "to"]

At a basic level, using localeCompare means you get actual alphabetic order. The sort is not going to treat the letters as if “H” comes before “a”. But it is doubly important because different languages have different orthographic rules.

For example, say you want to order city names for a Danish audience (this just as an example of weirdnesses that absolutely will not be picked up by basic sorting):

["Aachen", "Aarhus", "Berlin", "Zurich"]

That’s wrong, the Danish alphabetical order should be:

["Aachen", "Berlin", "Zurich", "Aarhus"]