Сортировка многомерного массива объектов
Есть массив, данные которого попадают в таблицу. Как написать функцию, которая будет сортировать его по value
объекта, id
которого я передаю. Например нужно отсортировать массив по возрастанию значения id == 2
[[
{
"id": 1,
"value": "Наименование 1"
},
{
"id": 2,
"value": 715322
},
{
"id": 3,
"value": 1003
},
{
"id": 4,
"value": 713.18
}
],
[
{
"id": 1,
"value": "Наименование 2",
},
{
"id": 2,
"value": 2293700
},
{
"id": 3,
"value": 3852
},
{
"id": 4,
"value": 595.46
}
]]
Обновление: Вот что мне удалось сделать
sortReportData(state, { id, asc }) {
console.log(asc)
state.reportData.rows.sort((a, b) => {
const valueA = a.find(item => item.id === id).value;
const valueB = b.find(item => item.id === id).value;
let comparison = 0;
if (typeof valueA === 'string' && typeof valueB === 'string') {
comparison = valueA.localeCompare(valueB);
} else {
comparison = valueA - valueB;
}
const data = asc ? comparison : -comparison
return data;
});
}
Ответы (2 шт):
Как написать функцию, которая будет сортировать его по value объекта, id которого я передаю.
Такое можно реализовать, например, так...
const a = data()
const id = 2
const asc = false
console.log(sortReportData(a, id, asc))
//
function sortReportData(arr, id, asc = false) {
const fn = o => o.id === id
return a.toSorted((a, b) => {
const v1 = a.find(fn)?.value
const v2 = b.find(fn)?.value
let v = ((typeof v1 === 'number') && (typeof v2 === 'number'))
? v1 - v2
: v1.toString().localeCompare(v2.toString())
return asc ? -v : v
})
}
//
function data() {
return [[
{
"id": 1,
"value": "Наименование 1"
},
{
"id": 2,
"value": 715322
},
{
"id": 3,
"value": 1003
},
{
"id": 4,
"value": 713.18
}
],
[
{
"id": 1,
"value": "Наименование 2",
},
{
"id": 2,
"value": 2293700
},
{
"id": 3,
"value": 3852
},
{
"id": 4,
"value": 595.46
}
]]
}
Предложу вариант преобразования многомерного массива в плоский, сортировку массива и возврат отсортированнного массива к исходному виду(это уменьшит количество внутренних переборов массивов при сортировке)
Изначально предполагается, что если передается id, то все значения value имеют одинаковый тип данных. В функции есть проверка на соответсвие типов сравниваемых значений, однако результат такой сортировки будет выглядеть странновато.
Если такие случае имеют место быть, надо будет придумать систему приведения значений к единому типу
function sortArr(arr, id, asc = false) {
return arr
// Создаем плоский массив из элементов по переданному id
.map((el, idx) => {
const resEl = { ...el.find(e => e.id === id) ?? { value: '' } };
resEl.id = idx;
return resEl;
})
// Сортируем массив
.sort((a, b) => {
if (typeof b.value === 'number' && typeof a.value === 'number') {
return asc ? a.value - b.value : b.value - a.value;
} else if (typeof b.value === 'string' && typeof a.value === 'string') {
return asc ? a.value.localeCompare(b.value) : b.value.localeCompare(a.value);
} else return 0;
})
// Собираем обратно массив по результатам сортировки
.map(el => arr[el.id]);
}
console.log(1, sortArr(generateData(), 1, true));
console.log(2, sortArr(generateData(), 2, false));
console.log(3, sortArr(generateData(), 3, true));
console.log(4, sortArr(generateData(), 4, false));
console.log(4, sortArr(generateData(), 4, true));
console.log(5, sortArr(generateData(), 5, true));
function generateData() {
return [
[
{
"id": 1,
"value": "Наименование 1"
},
{
"id": 2,
"value": 715322
},
{
"id": 3,
"value": 1003
},
{
"id": 4,
"value": 713.18
}
],
[
{
"id": 1,
"value": "Наименование 2",
},
{
"id": 2,
"value": 2293700
},
{
"id": 3,
"value": 3852
},
{
"id": 4,
"value": 595.46
}
],
[
{
"id": 1,
"value": "Наименование 3",
},
{
"id": 2,
"value": 229300
},
{
"id": 3,
"value": 38525
},
{
"id": 4,
"value": 95.46
}
],
[
{
"id": 1,
"value": "Наименование 4",
},
{
"id": 2,
"value": 3700
},
{
"id": 3,
"value": 1852
},
{
"id": 4,
"value": 895.46
}
],
[
{
"id": 1,
"value": "Наименование 5",
},
{
"id": 2,
"value": 1700
},
{
"id": 3,
"value": 852
}
],
[
{
"id": 1,
"value": "Наименование 6",
},
{
"id": 2,
"value": 1700
},
{
"id": 3,
"value": 852
},
{
"id": 4,
"value": 700
}
]
]
}