'Array sort is not working correctly in JavaScript [duplicate]
I have tried this code
function sort() {
var ary = [2, 1, 0.4, 2, 0.4, 0.2, 1.5, 1, 1.1, 1.3, 1.2, 0.2, 0.4, 0.9];
alert(ary.sort(function(a, b) {return a < b;}));
}
sort();
but the result is
[1, 2, 2, 1.1, 0.9, 1.2, 1.5, 1, 1.3, 0.4, 0.4, 0.4, 0.2, 0.2]
It works if length of array is short. But it doesn't work for long array. Thanks.
Solution 1:[1]
You sorting is failing because your comparison function does not meet the specifications for Array.sort:
- 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.
- compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If inconsistent results are returned then the sort order is undefined.
Your comparison function returns a boolean, which is effectively only returning the values 0 and 1. You should fix your comparison function according to the spec like in David's answer. Here's a simple comparison function1:
var ary = [2, 1, 0.4, 2, 0.4, 0.2, 1.5, 1, 1.1, 1.3, 1.2, 0.2, 0.4, 0.9];
console.log(ary.sort(compareDecimals));
function compareDecimals(a, b) {
if (a === b)
return 0;
return a < b ? -1 : 1;
}
The other answers (of using function { return a - b; } take advantage of mathematical coincidence. Namely that equal values have a difference of 0. This works for "normal" values, but it's prone to errors when your data contains values like Inifinity or Number.MIN_SAFE_INTEGER.
1. As noted in the comments, this function does not address all of the crazy javascript number behavior, for example that NaN === NaN evaluates to false. Likewise for dealing with mixed-type arrays. Engineer your comparison function as needed depending on the nature of your data.
Solution 2:[2]
Try:
var ary = [2, 1, 0.4, 2, 0.4, 0.2, 1.5, 1, 1.1, 1.3, 1.2, 0.2, 0.4, 0.9];
function compare(a, b) {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
}
ary = ary.sort(compare);
alert(ary);
Solution 3:[3]
Your code has a typo in alert.
Anyway the correct implementation is -
function sort() {
var ary = [2, 1, 0.4, 2, 0.4, 0.2, 1.5, 1, 1.1, 1.3, 1.2, 0.2, 0.4, 0.9];
return ary.sort(function(a, b) {return a - b;});
}
alert(sort());
outputs - [0.2, 0.2, 0.4, 0.4, 0.4, 0.9, 1, 1, 1.1, 1.2, 1.3, 1.5, 2, 2]
(use b - a to change the sort order).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | David Anthony Acosta |
| Solution 3 | planet_hunter |
