Sort Method not working

Tell us what’s happening:

Hi,

Can you please let me know why my sort method is not working? The order of the arrays doesn’t change when I run the tests.

Your code so far


function alphabeticalOrder(arr) {
  // Add your code below this line
  
  return arr.sort(function(a,b){return a>b; }); 

  
  // Add your code above this line
}
alphabeticalOrder(["a", "d", "c", "a", "z", "g"]);

console.log((alphabeticalOrder(["a", "d", "c", "a", "z", "g"]))); 

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36.

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

hi @Jessica2019

try to pass the arr to .sort() function. Like:
return arr.sort();

It should work.

I strongly recommend reading the Devdocs page on Array.sort (it’s exactly the same as the MDN page, but it’s devdocs…)

Now, here’s where it gets funky. If the return value of the comparison function is less than zero, it sorts one way - if greater than zero it sorts the other. And if the return value is exactly zero, it leaves the two elements as-is.

How does that work with the alphabetic sort? There are a few options, but I would suggest you take a look at that page I linked above, and scroll down till you see a section that talks about localeCompare() - it allows the sorting of alphabetic values, as well as extended alphabetic (accented letters, for example).

1 Like

Hmm, it appears that the lesson is wrong about the way sort handles non-numeric values.

From the lesson

function reverseAlpha(arr) {
  return arr.sort(function(a, b) {
    return a < b;
  });
}
reverseAlpha(['l', 'h', 'z', 'b', 's']);
// Returns ['z', 's', 'l', 'h', 'b']

But as you can see, running that on Codepen does not give the desired result. The console does not match the expected outcome:

As @snowmonkey points out, the sort function will deal with 1, 0, and -1 values. String comparison such as "a" > "b" can only return true or false.

So to fix this we need a slightly more complicated compare function:

expand for spoiler
function reverseAlpha(arr) {
  return arr.sort(function(a, b) {
    if (a < b) {
      return 1;
    } else if (a > b) {
      return -1
    } else {
      return 0;
    }
  });
}
console.log(reverseAlpha(['l', 'h', 'z', 'b', 's']));
// Returns ['z', 's', 'l', 'h', 'b']```

There are cleaner ways of writing that, but the logic is correct in my version of the reverseAlpha function, and should steer you in the right direction.

2 Likes

Hi @snowmonkey and @JacksonBates

Is mine code a good solution or a bad one? Or not correct in this case? What do you think guys?

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

Thanks! @JacksonBates @snowmonkey

However, i still don’t understand the role of the comparison function in the sorting process.

For example,

let arr = [4,7,9, 1, 8]
arr.sort (function (a,b) { return a -b});

In this case, which values does a and b carry in the sorting process exactly?

The a and b in the sort method will refer to 2 numbers in what you are trying to iterate over. For example, with this given array:

[1, 4, 3]

The comparison with a and b will start from the left moving on to the right of the array. So to start off with, a = 1 and b = 4. When you do a comparison of a - b in the sort method, if a - b equals a negative number, then that number, which is currently a, will be on the front of the array, if not then the numbers get swapped.

So now that the first comparison has been done, b will shift onto the next number in the array which will be 4, while a stays the same, until it has been compared to every single number in the array. And once the first iteration of a has been compared to everything, a will shift to the next number in the array and do the comparison all over again, thus giving you this array:

[1, 3, 4]
2 Likes

Since you are sorting on strings, just calling .sort() is good, as it will get the job done without doing anything else. However if you’re dealing with numbers, just calling sort can produce incorrect results, because sort deals with the values as strings. So you always want to do a comparison in your sort method such as a - b.

Got you!

Thank you very much for the explanation. :slight_smile:

@timagixe No problem!

@camperextraordinaire
That’s true, that would get rid some edge cases that can pop up when comparing strings. Just wasn’t sure if that has been introduced yet in this particular curriculum. Isn’t localeCompare slower than the regular sort as well?

Yes, but it’s the only realistic way to correctly sort alphabetically: sort() doesn’t really sort alphabetically (it is alphabetic only if you restrict it to ascii and one case), and the callback would need to check specific character sets to be able to do it accurately. So the following, for example, would work for the basic English alphabet (for a non-basic example, æther is a valid English word), but that’s all:

arr.sort((a, b) => {
  const lcA = a.toLowerCase();
  const lcB = b.toLowerCase();

  if (lcA < lcB) return -1;
  if (lcA === lcB) return 0;
  if (lcA > lcB) return 1;
});

That’s all that’s needed a lot of the time, and tbh just converting all character to lower- or uppercase then sorting is fine most of the time as well, so just arr.sort() assuming the conversion has already happened.

1 Like

I’d also suggest applying the toLocaleCompare method when sorting alphabetically.
Check the link for reference.

That’s true, I need to start using localeCompare more, it’s always in the back of my mind that it exists.

1 Like

You don’t need to pass that anonymous function into .sort(). It should work just fine after that.