Reputation: 29
Sorting multi-dimensional array in JavaScript. Perused other posts, but can't figure out how to pass the array members to the custom sort function, which determines whether to sort a string or numbers. Custom sort function is this:
function colSort(a, b) {
if (sortDown) dValue = 1
else dValue = -1;
if (isNumeric(a[sortIndex])) {
return (b[sortIndex] - a[sortIndex]) * dValue;
} else {
var astring = a[sortIndex].toLowerCase();
var bstring = b[sortIndex].toLowerCase();
if (bstring > astring) return -dValue;
if (bstring < astring) return dValue;
return 0;
}
}
Array looks like this:
var qbStats =[
['David Lea', 'GB', 343, 502, 68.3, 4643, 9.2, 45, 6, 122.5],
['Kevin Whyte', 'NO', 440, 622, 70.7, 5087, 8.2, 41, 13, 108.4]
]
The column headers in a HTML table listing array members should be able to be clicked to sort ascending/descending on the clicked column.
I can't figure out how to indicate members to be sorted on the clicked index.
I know it starts as:
qbStats.sort(colSort(a,b));
But I don't know how to pass the array members to be sorted on the specific index. Ex: How do I tell it to sort on 'GB'
and 'NO'
as 'a'
and 'b'
?
Thanks for any help you can give!
Upvotes: 2
Views: 159
Reputation: 386680
Maybe this is something for you. The function returns for any case the right function to compare.
var qbStats = [['David Lea', 'GB', 343, 502, 68.3, 4643, 9.2, 45, 6, 122.5], ['Kevin Whyte', 'NO', 440, 622, 70.7, 5087, 8.2, 41, 13, 108.4]];
function sort(column, sortOrder, isNumber) {
if (isNumber) {
if (~sortOrder) {
return function (a, b) {
return a[column] - b[column];
}
} else {
return function (a, b) {
return b[column] - a[column];
}
}
} else {
if (~sortOrder) {
return function (a, b) {
return a[column].localeCompare(b[column]);
}
} else {
return function (a, b) {
return b[column].localeCompare(a[column]);
}
}
}
}
qbStats.sort(sort(0, 1, false)); // sort 0th column, ascending by string
document.write('<pre>' + JSON.stringify(qbStats, 0, 4) + '</pre>');
qbStats.sort(sort(2, -1, true)); // sort 2th column, descending by number
document.write('<pre>' + JSON.stringify(qbStats, 0, 4) + '</pre>');
Upvotes: 0
Reputation: 413826
The comparison callback to the sort()
function is called by the sorting process and passed pairs of array elements. You don't have to tell anything which elements to compare; the sorting process already knows that.
In your case, the issue is that you essentially need a sort function per column. You can handle that by creating a function that returns another function, one that "knows" which column to compare:
function byColumn(sortIndex) {
return function colSort(a, b) {
if (sortDown) dValue = 1
else dValue = -1;
if (isNumeric(a[sortIndex])) {
return (b[sortIndex] - a[sortIndex]) * dValue;
} else {
var astring = a[sortIndex].toLowerCase();
var bstring = b[sortIndex].toLowerCase();
if (bstring > astring) return -dValue;
if (bstring < astring) return dValue;
return 0;
}
};
}
And then:
qbStats.sort(byColumn(4)); // sort by column 4
The byColumn()
function is just a simple wrapper around your comparator function. When it is called, it returns the actual function that the sort process will use. That function has access to the sortIndex
parameter that was passed in at its creation time, so it intrinsically "knows" how to compare two rows.
Upvotes: 1