Сортировать таблицу по подстроке

Я пытаюсь отсортировать таблицу по номеру курса, но мне нужно использовать подстроку для сортировки по номеру. Например, название курса выглядит как CX-001, я хочу проигнорировать первые три символа. Я использую Vanilla Javascript. Я не уверен, где применить подстроку, но знаю, что ошибся.

function sortSubNum(subNum) {
  var switchcount = 0;

  var table = document.getElementById("myTable2").substring(2);
  var switching = true;
  // Set the sorting direction to ascending:
  var dir = "asc";
  /* Make a loop that will continue until
  no switching has been done: */
  while (switching) {
    switching = false;
    var rows = table.rows;
    var shouldSwitch;
    for (var i = 1; i < (rows.length - 1); i++) {

      var x = rows[i].getElementsByTagName("TD")[subNum];
      var y = rows[i + 1].getElementsByTagName("TD")[subNum];
      //var resX = x.substring(2);
      //var resY = y.substring(2);

      if (dir === "asc") {
        if (Number(x.textContent.substring(2)) < Number(y.textContent.substring(2))) {
          //if so, mark as a switch and break the loop:
          shouldSwitch = true;
          break;
        }
      } else if (dir === "desc") {
        if (Number(x.textContent.substring(2)) > Number(y.textContent.substring(2))) {
          shouldSwitch = true;
          break;
        }
      }
    }
    if (shouldSwitch) {
      rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
      switching = true;
      switchcount++;
    } else {
      if (switchcount === 0 && dir === "asc") {
        dir = "desc";
        switching = true;
      }
    }
  }
}
sortSubNum(1);
<table id = "myTable2">
  <thead>
    <tr>
      <th>Teacher</th>
      <th>Course Number</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Smith</td>
      <td>CS-301</td>
    </tr>
    <tr>
      <td>Kelly</td>
      <td>CX-201</td>
    </tr>
    <tr>
      <td>Park</td>
      <td>CS-001</td>
    </tr>
  </tbody>
</table>

Вместо того, чтобы реализовывать свой собственный метод сортировки непосредственно в DOM, рассмотрите возможность инициализации Array элементов и вызова Array.prototype.sort(), а затем повторной вставки вновь упорядоченных элементов обратно в таблицу. Это будет намного быстрее и менее подвержено ошибкам.

Patrick Roberts 02.10.2018 17:22

Я буду иметь это в виду на будущее, я просто решил свою проблему самостоятельно, сделав несколько корректировок.

James Parker 02.10.2018 17:33

@JamesParker Вы можете ответить на свой вопрос. Таким образом, это может помочь найти это в будущем.

Dexygen 02.10.2018 17:39

@GeorgeJempty, спасибо, что указали на это. Я немного новичок в этом.

James Parker 02.10.2018 18:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
111
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Удалена подстрока из таблицы var. Кроме того, я изменил условные выражения в цикле for с

if (Number(x.textContent.substring(2)) < Number(y.textContent.substring(2)))

к

if (x.textContent.substring(2) < y.textContent.substring(2))

function sortSubNum(subNum) {
    var switchcount = 0;

    var table = document.getElementById("myTable2");
    var switching = true;
    // Set the sorting direction to ascending:
    var dir = "asc"; 
    /* Make a loop that will continue until
    no switching has been done: */
    while(switching){
        switching = false;
        var rows = table.rows;
        var shouldSwitch;
        for(var i = 1; i < (rows.length - 1); i ++){

            var x = rows[i].getElementsByTagName("TD")[subNum];
            var y = rows[i + 1].getElementsByTagName("TD")[subNum];
            //var resX = x.substring(2);
            //var resY = y.substring(2);

            if (dir === "asc"){
                if (x.textContent.substring(2) < y.textContent.substring(2)) {
                    //if so, mark as a switch and break the loop:
                    shouldSwitch = true;
                    break;
                }
            }else if (dir === "desc"){
                if (x.textContent.substring(2) > y.textContent.substring(2)){
                    shouldSwitch = true;
                    break;
                }
            }
        }
        if (shouldSwitch){
            rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
            switching = true;
            switchcount++;
        }else{
            if (switchcount === 0 && dir === "asc") {
                dir = "desc";
                switching = true;
            }
        }
    }
}

Хотя вы уже обнаружили проблему в своем коде, но мое решение основано на предложении @Patrick Roberts, приведенном в комментарии.

Instead of implementing your own sorting method directly on the DOM, consider initializing an Array of elements and calling Array.prototype.sort(), then reinserting the newly ordered elements back into the table. It would be a lot faster and less error-prone

function sortTable(tbody, col, asc){
    var rows = tbody.rows;
    var rowsLen = tbody.rows.length;
    var arr = new Array();
    var i, j, cells, cellLen;
    // fill the array with values from the table
    for(i = 0; i < rowsLen; i++){
    cells = rows[i].cells;
    cellLen = cells.length;
    arr[i] = new Array();
        for(j = 0; j < cellLen; j++){
          arr[i][j] = cells[j].innerHTML;
        }
    }
    //short the array
    arr.sort(function(a, b){
       //this is your use case.sort the data in array after spilt.
       var aCol=a[col].split("-")[1];
       var bCol=b[col].split("-")[1];
       return (aCol == bCol) ? 0 : ((aCol > bCol) ? asc : -1*asc);
    });
    
    for(i = 0; i < rowsLen; i++){
        arr[i] = "<td>"+arr[i].join("</td><td>")+"</td>";
    }
    tbody.innerHTML = "<tr>"+arr.join("</tr><tr>")+"</tr>";
}
var tbody=document.getElementById("myTable2Tbody");
sortTable(tbody,1, 1);
//for asc use 1,for dsc use -1
<table id  = "myTable2">
    <thead>
        <tr>
            <th>Teacher</th>
            <th>Course Number</th>
        </tr>
    </thead>
    <tbody id  = "myTable2Tbody">
        <tr>
            <td>Smith</td>
            <td>CS-301</td>
        </tr>
        <tr>
            <td>Kelly</td>
            <td>CX-201</td>
        </tr>
        <tr>
            <td>Park</td>
            <td>CS-001</td>
        </tr>        
    </tbody>
</table>

Спасибо за это. Мне нравится такой подход

James Parker 05.10.2018 20:10

Проверьте это решение с помощью Array.sort

var tbody = document.querySelector('#myTable2 tbody')
var trs = tbody.querySelectorAll('tr')

var sorted = [...trs].sort((tra, trb) => {
    var courseA = tra.querySelectorAll('td')[1].innerText
    var courseB = trb.querySelectorAll('td')[1].innerText

    return courseA.split('-')[1] - courseB.split('-')[1]
})

tbody.innerHTML = '';
sorted.forEach(tr => tbody.appendChild(tr))
<table id = "myTable2">
    <thead>
        <tr>
            <th>Teacher</th>
            <th>Course Number</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Smith</td>
            <td>CS-301</td>
        </tr>
        <tr>
            <td>Kelly</td>
            <td>CX-201</td>
        </tr>
        <tr>
            <td>Park</td>
            <td>CS-001</td>
        </tr>
    </tbody>
</table>

Другие вопросы по теме