Reputation: 31
While using sort() method in Javascript, I'm not able to correctly sort an array of more than 10 objects. This happens only in Google Chrome; with Firefox and IE it works.
I have an array of 11 objects with two properties, number and name; I'd like to order these object per number and then per name, but with Chrome it doesn't work.
This is the code of the whole page:
<!DOCTYPE html>
<HTML>
<HEAD>
<SCRIPT>
var availableTags = [
{number: 0,name:"Consigli"},
{number: 0,name:"De sanctis"},
{number: 0,name:"Perin"},
{number: 1,name:"Bonucci"},
{number: 2,name:"Essien"},
{number: 2,name:"Florenzi"},
{number: 2,name:"Hernanes"},
{number: 2,name:"Martinho"},
{number: 2,name:"Montolivo"},
{number: 2,name:"Parolo"},
{number: 2,name:"Perez"}
];
function sortPlayers(a, b) {
var result = (parseInt(a.number) > parseInt(b.number));
if( (!result) && (parseInt(a.number) == parseInt(b.number)) ) {
result = a.name.toLowerCase().localeCompare(b.name.toLowerCase());
}
return result;
}
function updateFormation() {
availableTags.sort( sortPlayers );
var html = "";
for (var i = 0; i < availableTags.length; i++) {
html += availableTags[i].number + " " + availableTags[i].name + "\n";
}
alert(html);
}
</SCRIPT>
</HEAD>
<BODY>
<script type="text/javascript">
updateFormation();
</script>
</BODY>
At the following link: http://blog.rodneyrehm.de/archives/14-Sorting-Were-Doing-It-Wrong.html I read that "Chrome will sort arrays using InsertionSort if the array has 10 or less elements.": maybe this may help...
Does anybody can help me?
Upvotes: 3
Views: 2737
Reputation: 239623
Array.prototype.sort
method expects the sort helper method to return three different types of values.
1. Negative number - If the first element is smaller 2. Positive number - If the second element is smaller 3. Zero - If both the elements are equal
So, your sortPlayers
has to be tweaked a little, like this
function sortPlayers(a, b) {
if (a.number === b.number) {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
} else {
return a.number > b.number ? 1 : -1;
}
}
Since a.number
and b.number
are actually integers, you can straight away write like this
return a.number - b.number;
Upvotes: 5
Reputation: 25682
You have mistake at this line:
var result = (parseInt(a.number) > parseInt(b.number));
it should be:
var result = (parseInt(a.number) - parseInt(b.number));
sort
accepts callback, which should return negative number, positive number or zero. In your code when result
is true
the function sortPlayers
returns true
.
Since if result
is 0
a.number
and b.number
will be equal your function could be transformed to:
function sortPlayers(a, b) {
var result = (parseInt(a.number) - parseInt(b.number));
if (!result) {
result = a.name.toLowerCase().localeCompare(b.name.toLowerCase());
}
return result;
}
Upvotes: 0
Reputation: 707876
The sort callback function needs to return negative, 0 or positive number. You are returning a boolean in some cases which can yield inconsistent results and does not match the specification. A simple subtraction of two comparison numbers yields the proper negative, 0 or positive result that the comparison function needs:
function sortPlayers(a, b) {
var result = a.number - b.number;
if (result !== 0) {
return result;
}
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
}
Working demo: http://jsfiddle.net/jfriend00/Q6Qa2/
In addition, there is no need to use parseInt()
on things that are already numbers. And, if you did use parseInt()
, you MUST pass the radix value (the second argument) or parseInt()
may wrongly guess the radix value.
Upvotes: 1