Reputation: 6147
Could someone help me modify this code to support numerical sorting. Currently it only supports sorting alphabetically and I'm not a js writer myself, i found this online. I only need it to sort numerical, not alphabetical.
bonus: would it be possible to make it support numbers and strings
Here is the working link of it sorting alphabetical. jsfiddle.net
Thank you.
function sortTable(table, col, reverse) {
var tb = table.tBodies[0], // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
tr = Array.prototype.slice.call(tb.rows, 0), // put rows into array
i;
reverse = -((+reverse) || -1);
tr = tr.sort(function (a, b) { // sort rows
return reverse // `-1 *` if want opposite order
* (a.cells[col].textContent.trim() // using `.textContent.trim()` for test
.localeCompare(b.cells[col].textContent.trim())
);
});
for(i = 0; i < tr.length; ++i) tb.appendChild(tr[i]); // append each row in order
}
function makeSortable(table) {
var th = table.tHead, i;
th && (th = th.rows[0]) && (th = th.cells);
if (th) i = th.length;
else return; // if no `<thead>` then do nothing
while (--i >= 0) (function (i) {
var dir = 1;
th[i].addEventListener('click', function () {sortTable(table, i, (dir = 1 - dir))});
}(i));
}
function makeAllSortable(parent) {
parent = parent || document.body;
var t = parent.getElementsByTagName('table'), i = t.length;
while (--i >= 0) makeSortable(t[i]);
}
window.onload = function () {makeAllSortable();};
Upvotes: 3
Views: 4893
Reputation: 114481
You should change the comparison code to
return reverse * ((+a.cells[col].textContent) - (+b.cells[col].textContent))
the unary +
in Javascript can be used to convert a string to its numeric value.
Sorting a single column that can contain both numbers and non-numbers is trickier because you need to establish a transitive sorting criteria... for example:
in code:
function xcmp(a, b) {
if (isNan(a)) {
if (isNan(b)) {
return a.localeCompare(b);
} else {
return +1; // a non-numeric, b numeric: a > b
}
} else {
if (isNan(b)) {
return -1; // a numeric, b non-numeric: a < b
} else {
return a - b;
}
}
}
Simpler criteria like "compare them as numbers if both are numbers and as strings otherwise" don't work well because
i.e. you can create logical "loops" for which the very concept of sorting doesn't make sense.
Upvotes: 1
Reputation: 5356
This is working in both string and numbers
if(!isNaN(a.cells[col].textContent) && !isNaN(b.cells[col].textContent))
return reverse * ((+a.cells[col].textContent) - (+b.cells[col].textContent))
return reverse // `-1 *` if want opposite order
* (a.cells[col].textContent.trim() // using `.textContent.trim()` for test
.localeCompare(b.cells[col].textContent.trim())
);
https://jsfiddle.net/oqr0mjc6/3/
Upvotes: 3
Reputation: 805
In your sort function you can try to transform the a.cells[col].textContent.trim()
into a number. If it is not a number you compare it lexiografically, otherwise you compare the numbers
Upvotes: 0