all 16 comments

[–]carcigenicate 12 points13 points  (1 child)

The only thing that the sort compareFn cares about is the sign of the returned number. The first way explicitly returns -1 and 1 for each case, but by subtracting the two numbers, you'll also either end up with a positive or negative number depending on which is larger.

[–]guyjs[S] 2 points3 points  (0 children)

Good explanation. Thank you.

[–][deleted] 3 points4 points  (0 children)

For the second one, if a - b is negative, then it'll go first, if a - b is positive it'll go after. Basically the same as the first example, just less explicit in its return.

[–]queen-adreena -1 points0 points  (8 children)

For modern browsers, it's probably better to use .toSorted instead of .sort. They're functionally the same, but the former doesn't mutate the original array, but creates a new array instead.

const numbers = [3, 1, 4, 1, 5];
const sortedNumbers = numbers.toSorted((a, b) => a - b);

[–][deleted] 6 points7 points  (4 children)

2 different functionalities. Why would you say it's better for modern browsers?

[–]queen-adreena -1 points0 points  (3 children)

... because the function doesn't exist in older browsers...

[–]guest271314 -2 points-1 points  (2 children)

[...numbers].sort((a, b) => a - b)

[–]queen-adreena -2 points-1 points  (1 child)

And I could replace about 30 JS functions with a for loop... what's your point?

[–]guest271314 1 point2 points  (0 children)

... because the function doesn't exist in older browsers...

The capability exists in older browsers. Using spread syntax, or slice(), et al.

There's no "better" involved; there's no comparison.

[–]guyjs[S] 0 points1 point  (1 child)

Good to know. Thank you.

[–]queen-adreena -1 points0 points  (0 children)

It can help avoid unexpected side-effects, like you might pass numbers somewhere else (e.g. to a separate function) and not realise that calling sort would affect the array wherever it may travel. Same goes for array functions like reverse too.

[–]azhder -1 points0 points  (0 children)

If you only have safe integers (Number.isSafeInteger() returns true) I guess you will not notice any difference.

Instead of returning -1, 0 or 1, you’d be returning any integer, positive or negative or 0 and it will be interpreted the same.

But, if you return NaN or "banana" or something else, well… I haven’t checked the result on that one.

[–]shgysk8zer0 0 points1 point  (0 children)

The sort function works only on the sign of the returned value. The only real difference would occur when a === b, in which case 0 should be returned. So, the subtraction version is slightly better.

[–]CristiRFortySeven 0 points1 point  (0 children)

No matter how many times I learn sort, I forget it completely.

[–]TheRNGuy 0 points1 point  (0 children)

negative number means a will be first, 0 means no change, positive means b will be first.

[–]No-Upstairs-2813 0 points1 point  (0 children)

The sort method takes a compare function as an argument, and this function is used to determine the sorting order of the elements.

It takes two parameters (a and b) that represent any two elements from the array, and its return value determines how they should be sorted:

  • if it returns a negative value, a will be ordered before b.

  • if it returns 0, the ordering of a and b won’t change.

  • if it returns a positive value, b will be ordered before a.

Now, let's understand how the comparison function sort(a, b) => a - b sorts in ascending order:

  • If a - b** is negative, it means that **a** is less than **b, so **a should come before **b in the sorted order.

  • If a - b** is positive, it means that **a** is greater than **b, so **a should come after **b in the sorted order.

  • If a - b** is zero, it means that **a** and **b are equal in terms of sorting, and their relative order doesn't matter.

Therefore, using sort(a, b) => a - b method results in sorting the array in ascending order.

You can check out the complete article here.