Search code examples
javascriptsortingdomtablesorter

How to sort balance in table ascending and descending?


I was try sort the balance in table an ascending and an descending, but can't. I looked the w3schools tutorial and theme in stackoverflow about insertBefore and insertAfter without libraries. But isn't works. My code:

function sortTableByBalance() {
  let table, rows, switching, i, x, y, shouldSwitch;
  table = document.getElementById("myTable");
  switching = true;

  while (switching) {
    switching = false;
    rows = table.rows;

    for (i = 1; i < rows.length - 1; i++) {
      shouldSwitch = false;

      x = rows[i].getElementsByTagName("TD")[2];
      y = rows[i + 1].getElementsByTagName("TD")[2];

      if (Number(x.innerHTML) > Number(y.innerHTML)) {
        shouldSwitch = true;
        break;
      } else if (Number(x.innerHTML) < Number(y.innerHTML)) {
        shouldSwitch = false;
        break;
      }
    }

    if (shouldSwitch) {
      rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
      switching = true;
    }
      else if (!shouldSwitch) {
      rows[i].parentNode.insertBefore(rows[i + 1], rows[i].nextSibling);
       switching = true;
     }
  }
}

Solution

  • The reason your table doesn't get sorted is that you break out of the loop when a pair of balances is not equal. Apparently you wanted to implement some sort of bubble sort, but by exiting the inner loop when you set shouldSwitch to false, that algorithm is not correctly implemented: it will not detect that a next pair is not in the correct order.

    So the quick fix is to change this:

      } else if (Number(x.innerHTML) < Number(y.innerHTML)) {
        shouldSwitch = false;
        break;
    

    to this:

      } else if (Number(x.innerHTML) < Number(y.innerHTML)) {
        shouldSwitch = false;
    

    Better approach

    However, you should not have to implement a sort algorithm explicitly. There is sort and you can rely on it for this table sorting as well:

    function sortTableByBalance() {
        const table = document.getElementById("myTable");
        const arr = Array.from(table.rows, row => [row, +row.cells[2].textContent]).slice(1);
        arr.sort(([,a], [,b]) => a - b);
        for (const [elem] of arr) {
            table.appendChild(elem);
        }
    }