art9mid
@art9mid
front-end

Как отсортировать табличные значения?

5f954c1bdad00824792103.png
Как отсортировать таблицу по возрасту?

<table id="grid">
    <thead>
      <tr>
        <th data-type="number">Возраст</th>
        <th data-type="string">Имя</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>5</td>
        <td>Вася</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Петя</td>
      </tr>
      <tr>
        <td>12</td>
        <td>Женя</td>
      </tr>
      <tr>
        <td>9</td>
        <td>Маша</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Илья</td>
      </tr>
    </tbody>
  </table>
  • Вопрос задан
  • 93 просмотра
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
Сделаем объект, где ключами будут имена типов данных, а значениями - функции сравнения значений соответствующих типов:

const sort = {
  number: (a, b) => a - b,
  string: (a, b) => a.localeCompare(b),
};

Функция сортировки - принимает таблицу (может быть передана в виде элемента или селектора) и индекс столбца, по значениям которого надо отсортировать строки. По индексу столбца стучимся в его заголовок, получаем из него имя типа данных, по имени типа извлекаем функцию сравнения. Из тела таблицы достаём строки, превращаем их в массив, сортируем, добавляем обратно:

function sortTable(table, colIndex) {
  if (typeof table === 'string') {
    table = document.querySelector(table);
  }

  const head = table.tHead.rows[0];
  const compare = sort[head.cells[colIndex].dataset.type] ?? sort.string;
  const value = row => row.cells[colIndex].innerText;
  const tbody = table.tBodies[0];

  tbody.append(...[...tbody.rows].sort((a, b) => compare(value(a), value(b))));
  [...head.cells].forEach((n, i) => n.classList.toggle('sorted', i == colIndex));
}

Стилизуем заголовок столбца, по которому выполнена сортировка:

.sorted {
  background: #ccc;
}
.sorted::after {
  content: " \2193";
}

Всё, можно пользоваться:

// просто дёргаем сортировку
sortTable('#grid', 0);
sortTable(document.querySelector('table'), 1);

// или, сортируем по клику на заголовки столбцов
document.querySelectorAll('#grid th').forEach(function(n) {
  n.addEventListener('click', this);
}, ({ target: t }) => sortTable(t.closest('table'), t.cellIndex));
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы