(Fixed, bug on Chrome, not on Firefox)Find a bug, Functional Programming: Sort an Array Alphabetically using the sort Method

Even I write correct code, or copy form “Get a Hint”.

I still can’t get passed.

Hey @i-python-com, welcome to the forum!

Could you show us the solution that you submitting that’s not passing the tests?

The hint stopped being correct for Chrome about October, when Chrome changed the way its sort algorithm worked. There is a fix ready on FCC, but it takes time for it to get live. Basically, I can’t see your code, but I’m guessing it isn’t correct: look at the documentation for sort – the callback function should return -1, 0 or 1, not true or false. If it does return -1, 0 or 1, then it will work. If it returns true or false, it isn’t going to work.

Sorry for reply you late. The solution in Chrome doesn’t work, but the same code in Firefox works.

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

So this is actually not a bug, but a common mistake that I make all the time.

Similar to what @DanCouper mentioned, the compare function spec is supposed to return greater than 0, less than 0, or just 0. Returning the comparison using < or > returns a Boolean, which is technically undefined behavior and I’m guessing that Firefox’s engine somehow just works with it.

as @DanCouper said above:

For right now Firefox and Chrome are both working after updated the Chrome.

That documentation confuse me. The compare function return boolean still get corrected sort result.

true, false, 1, 0, -1

JS tends to coerce values. It is extremely weakly typed. true/false -> 1/0 (or vice versa). So even though the callback seemingly returns the wrong thing (a boolean), sort expects a number as a return value, so a number is what it gets in many cases. The “bug” where it doesn’t work is to do with browser implementation: there is no reason why a browser vendor can’t decide to change how strictly this is applied (the actual specification is quite vague and leaves it up to the authors of any given JS implementation).

Thanks.
That’s meaning the JavaScript engine in browser decide transfer the boolean to numbers.

But the engine in Chrome and engine in Firefox doing different thing.

It’s to more do with what they’re trying to do. The spec doesn’t specify whether sort should be stable or not. “Stable” means that if any values are the same, once the sort happens they should return in the same order they were input as. For a simple example:

[9, 8, 4, 1, 5, 4, 3].sort()

If you want a stable sort, the first four should be before the second four in the sorted result, eg

> [9, 8, 4a, 1, 5, 4b, 3].sort()
[1, 3, 4a, 4b, 5, 8, 9]

If you don’t return the proper -1/0/1 I don’t see how you can guarantee that ordering, and that ordering seems to be what certain vendors want, hence why in Chrome for example the example solution didn’t work.

Also just for reference, by specification I mean this: https://www.ecma-international.org/ecma-262/9.0/index.html (it’s just algorithms, it doesn’t specify what language JS has to be written in or anything like that)

Interesting…

['l', 'h', 'z', 'b', 's'].sort(function(a, b) {
	return a.charCodeAt() - b.charCodeAt();
})
(5) ["b", "h", "l", "s", "z"]


['l', 'h', 'l2','z', 'b','lz', 's'].sort(function(a, b) {
	return a.charCodeAt() - b.charCodeAt();
})
(7) ["b", "h", "l", "l2", "lz", "s", "z"]


[ 'l2', 'l', 'h','z', 'b','lz', 's'].sort(function(a, b) {
	return a.charCodeAt() - b.charCodeAt();
})
(7) ["b", "h", "l2", "l", "lz", "s", "z"]

Yep, without stable sort you get inconsistent results in certain situations.

For what it’s worth, ECMAScript 2019 does require the sort to be stable.

18. Stable Array.prototype.sort()

Starting with ECMAScript 2019, the Array method .sort() is guaranteed to be stable.

ECMAScript Latest Draft (ECMA-262)

22.1.3.27 Array.prototype.sort ( comparefn )

The elements of this array are sorted. The sort must be stable (that is, elements that compare equal must remain in their original order).