Почему не сортирует массив если в поле приходит number?
Есть такая вот функция сортировки.
const onSort = (sortField) => {
const data = [...programs];
data.sort((a, b) => (a[sortField] - b[sortField] ? 1 : -1));
setPrograms(data);
};
И в таблице есть div при клике по которому происходит сортировка массива.
<div
className="table__col--listener"
onClick={() => onSort("listener")}
>
Массив:
const mockPrograms = [
{
id: 1,
name: "Программирование на языке Python",
date: "07.05.2020",
listener: "Тест К. С.",
mail: 10,
status: 1,
},
{
id: 2,
name: "Малярные и декоративные работы",
date: "12.06.2020",
listener: "Тестов К. С.",
mail: 5,
status: 2,
},
];
По date, listener где в значениях string всё в порядке сортирует, а если приходит number как в status то не хочет.
Ответы (2 шт):
Странно, что у вас по строке все правильно сортируется. Наверное, это простая случайность
Выражение
a[sortField] - b[sortField] ? 1 : -1
Даст -1 только в случае, если a[sortField] - b[sortField] = 0;
Вероятнее всего, вы хотите получить что-то вроде:
// Из вашего кода не особо понятно, какой порядок сортировки вам нужен
data.sort((a, b) => a[sortField] - b[sortField]); // status: 1 будет идти раньше чем status: 2
data.sort((a, b) => b[sortField] - a[sortField]); // наоборот
А если есть необходимость сравнивать строки, то обязательно приводите к одному кейсингу. Строки посимвольно конвертируются в числовые значения по таблице ASCII, поэтому слова, начинающиеся с большой буквы всегда будут идти раньше слов с маленькой:
data.sort((a, b) => {
if (typeof a[sortField] === 'string') {
return a[sortField].toLowerCase() < b[sortField].toLowerCase() ? -1 : 1;
}
return b[sortField] - a[sortField];
});
Если необходимо менять направление сортировки, объявите переменную вне функции сортировки.
let direction = 1;
В самой функции проверяйте поле сортировки. Если пришло то же поле, то меняйте значение сортировки на -1.
let sortField;
function onSort(criteria) {
if (sortField === criteria) {
direction *= -1;
} else {
direction = 1;
}
sortField = criteria;
...
data.sort((a, b) => (a[sortField] - b[sortField]) * direction);
}
const onSort = (sortField) => {
const data = mockPrograms;
data.sort((a, b) => ((a[sortField] - b[sortField]) >= 0 ? 1 : -1));
setPrograms(data);
};
const mockPrograms = [{
id: 1,
name: "Программирование на языке Python",
date: "07.05.2020",
listener: "Тест К. С.",
mail: 10,
status: 1,
},
{
id: 2,
name: "Малярные и декоративные работы",
date: "12.06.2020",
listener: "Тестов К. С.",
mail: 5,
status: 2,
},
];
function setPrograms(data) {
for (let i = 0; i < data.length; i++) {
document.getElementById(`tr${i}`).innerHTML = `<td>${data[i].id}</td><td>${data[i].name}</td><td>${data[i].date}</td><td>${data[i].listener}</td><td>${data[i].mail}</td><td>${data[i].status}</td>`;
}
}
setPrograms(mockPrograms);
td{border: 1px solid black;
<table>
<tr>
<td class="table__col--listener" onClick="onSort('id')">id</td>
<td class="table__col--listener" onClick="onSort('name')">name</td>
<td class="table__col--listener" onClick="onSort('date')">date</td>
<td class="table__col--listener" onClick="onSort('listener')">listener</td>
<td class="table__col--listener" onClick="onSort('mail')">mail</td>
<td class="table__col--listener" onClick="onSort('status')">status</td>
</tr>
<tr id="tr0"></tr>
<tr id="tr1"></tr>
</table>