3

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();};

3 Answers 3

3

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/

Sign up to request clarification or add additional context in comments.

2 Comments

The problem of this approach is that "2" < "10" < "10a" < "2" i.e. transitivity doesn't hold. Sorting using a non-transitive criteria is madness.
hey @Man Programmer would you be able to convert this jsfiddle.net/JokerMartini/ctq3w7sj you helped me with, so it uses jquery and not pure complex javascript?
1

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:

  • all number-like strings come before other strings
  • number-like strings are sorted according to numeric value
  • other strings are sorted alphabetically

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

  • "2" < "10"
  • "10" < "10a"
  • "10a" < "2"

i.e. you can create logical "loops" for which the very concept of sorting doesn't make sense.

2 Comments

would there be a way to make the item work with both numbers and strings?
@JokerMartini: html cannot contain numbers... it's all text. Do you mean saying that both "10" > "2" but "abc" < "bcd"? What about the string "10,000,000" ? is it a number ?
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.