Functional Programming: Sort an Array Alphabetically using the sort Method

Functional Programming: Sort an Array Alphabetically using the sort Method
0

#1

Evening Fellow Campers

Can someone possibly explain to me why I’m not passing the test on

https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/functional-programming/sort-an-array-alphabetically-using-the-sort-method/

function alphabeticalOrder(arr) {
  // Add your code below this line
  
  arr.sort(function(a,b){
    return a > b;
  });
  console.log(arr);
  // Add your code above this line
}
alphabeticalOrder(["a", "d", "c", "a", "z", "g"]);

According to my logs, all the arrays are put in alphabetical order.

Thoughts much appreciated.

Gerald


#2

Because you are not returning the result.

return your arr.


#3

Dang. Faster fingers than me, @shimphillip. :wink:


#4

I knew it was something simple.

Many thanks


#5

Your sort callback is incorrect. The way to return is:

  • a < b Return less than 0
  • a = b Return exactly 0
  • a > b Return more than 0

And, your function returns a > b

Now, when a > b, you get true. This is indeed more than 0.

However, when a < b, you get false. This is equal to 0. Your sort might technically work (or not), but it’s very unstable and I wouldn’t be surprised if it would return incorrect results sometimes.

You could use String.prototype.localeCompare, but that’s unstable – it relies on the user’s locale. I would never use it, it runs differently when you change the language of the browser.

The best thing is to convert true (1) and false (0) into a positive and negative value respectively. There are many ways, pick the prettiest:

  • (a > b) * 2 - 1
  • (a > b) ? 1 : (a === b ? -1 : 0)
  • etc.

#6

Do you have a reference you could suggest? I’ve always simply done as the OP, i’d be curious to benchmark and test both.


#7

ECMAScript spec.

First of all, from the ECMASCript specification:

The elements of this array are sorted. The sort is not necessarily stable (that is, elements that compare equal do not necessarily remain in their original order). If comparefn is not undefined, it should be a function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if x > y.

And, if you take a look

The notation a <CF b means comparefn(a,b) < 0; a =CF b means comparefn(a,b) = 0 (of either sign); and a >CF b means comparefn(a,b) > 0.

If a =CF b, then b =CF a (symmetry)

That line from the specification means that if do compareFunction("a", "b") and you get 0; you must get 0 when you do compareFunction("b", "a"). You don’t. Because “0” signifies equivalence.

Because the comparison function isn’t consistent, the specification says that the sort order is “implementation-defined” according to the specification. You can’t know what it will sort to.

MDN docs

The MDN docs generally just interpret the ECMAScript specification and make it easier to understand.

  • If compareFunction(a, b) is less than 0, sort a to an index lower than b, i.e. a comes first.
  • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
  • If compareFunction(a, b) is greater than 0, sort b to an index lower than a, i.e. b comes first.

My bold. So the sort function is supposed to return “0” only for equality, and while most browsers probably will leave the sort order unchanged, there is no guarantee

Real-world example

As stated above in the MDN docs, most browsers treat “0” as keep-same-order. However, they just do it because they feel like it. They’d still be running the JavaScript correctly if they returned to you [“bananas”], if I’m not mistaken.

In a code golf StackExchange question, we had to sort numbers based on whether they were even or odd. I tried to return false and true. However, somebody found a very long array [-5…20] which broke it! This was in Chrome.

I was so sure it worked. Anywho, if you’re just sorting numbers normally, you might be safe in modern browsers, but it’s a good practice that might make you compatible with a much wider variety of JavaScript engines — as MDN said, Firefox before 2003 did not guarantee “0” means “-1” — because it’s simply not in the specification. :slightly_smiling_face:


#8

Thank you for the clear explanation, definite food for thought.