I have this array
const rows = [
{data: [{text: "A",value: 100}, {text: "B",value: 74}], group: "Elephant"},
{data: [{text: "C",value: 63}, {text: "D",value: 1}], group: "Elephant"},
{data: [{text: "E",value: 37}, {text: "F",value: 54}], group: "Penguin"},
{data: [{text: "G", value: 72}, {text: "H", value: 74}], group: "Lion"},
{data: [{text: "K", value: 76}, {text: "L", value: 38}], group: "Zebra"},
{data: [{text: "M", value: 68}, {text: "N", value: 21}], group: "Lion"},
];
And these sort functions
const _sortFunction = (
a,
b,
columnIndex,
sortOrder
) => {
if (a && a.data && b && b.data) {
if (a.data[columnIndex].value === b.data[columnIndex].value) {
return 0;
} else {
if (sortOrder === "ASC") return a.data[columnIndex].value > b.data[columnIndex].value ? -1 : 1;
if (sortOrder === "DESC") return a.data[columnIndex].value < b.data[columnIndex].value ? -1 : 1;
return 0;
}
} else {
return 0;
}
};
const sortRowsByColumn = (rows, sortProps) => {
if (sortProps && rows) {
const {indexOfColumnToSort, sortOrder} = sortProps;
const rowsCopy = JSON.parse(JSON.stringify(rows))
return rowsCopy.sort((a, b) => _sortFunction(a, b, indexOfColumnToSort, sortOrder));
}
return rows;
};
Which gives me console.log(sortRowsByColumn(rows, {indexOfColumnToSort: 1, sortOrder: "ASC"}))
[
{data: [{text: "A", value: 100}, {text: "B", value: 74}], group: "Elephant"},
{data: [{text: "G", value: 72}, {text: "H", value: 74}], group: "Lion"},
{data: [{text: "E", value: 37}, {text: "F", value: 54}], group: "Penguin"},
{data: [{ text: "K", value: 76}, {text: "L", value: 38}], group: "Zebra"},
{data: [{text: "M", value: 68}, {text: "N", value: 21}], group: "Lion"},
{data: [{text: "C", value: 63}, {text: "D", value: 1}],group: "Elephant"}
]
However, what I cannot get my head around is the following:
The updated sortRowsByColumn() function should
- sort the
rowsarray based on thegroupkey (alphabetically) - then sort based on the column index for each group
all of this without loosing the original array structure. Basically like a grouping and sorting for each group, without modifiying the array structure or the original array.
The result should look like this
[
{data: [{text: "A",value: 100}, {text: "B", value: 74}], group: "Elephant"},
{data: [{text: "C", value: 63}, {text: "D", value: 1}], group: "Elephant"},
{data: [{text: "G", value: 72}, {text: "H", value: 74}], group: "Lion"},
{data: [{text: "M", value: 68}, {text: "N", value: 21}], group: "Lion"},
{data: [{text: "E",value: 37}, {text: "F", value: 54}], group: "Penguin"},
{data: [{text: "K", value: 76}, {text: "L", value: 38}], group: "Zebra"},
]
>Solution :
I add sample code below.
const _sortFunction = (
a,
b,
columnIndex,
sortOrder
) => {
if (a && a.data && b && b.data) {
if (a.data[columnIndex].value === b.data[columnIndex].value) {
return 0;
} else {
if (sortOrder === "ASC") return a.data[columnIndex].value > b.data[columnIndex].value ? -1 : 1;
if (sortOrder === "DESC") return a.data[columnIndex].value < b.data[columnIndex].value ? -1 : 1;
return 0;
}
} else {
return 0;
}
};
const sortRowsByColumn = (rows, sortProps) => {
if (!sortProps || !rows) {
return rows;
}
const {
indexOfColumnToSort,
sortOrder
} = sortProps;
const groupedAndSortedRows = [...rows].sort((a, b) =>
a.group.localeCompare(b.group) || _sortFunction(a, b, indexOfColumnToSort, sortOrder)
);
groupedAndSortedRows.forEach(row =>
row.data.sort((a, b) => _sortFunction(a, b, indexOfColumnToSort, sortOrder))
);
return groupedAndSortedRows;
};
// Example usage
const rows = [
{data: [{text: "A",value: 100}, {text: "B",value: 74}], group: "Elephant"},
{data: [{text: "C",value: 63}, {text: "D",value: 1}], group: "Elephant"},
{data: [{text: "E",value: 37}, {text: "F",value: 54}], group: "Penguin"},
{data: [{text: "G", value: 72}, {text: "H", value: 74}], group: "Lion"},
{data: [{text: "K", value: 76}, {text: "L", value: 38}], group: "Zebra"},
{data: [{text: "M", value: 68}, {text: "N", value: 21}], group: "Lion"},
];
console.log(sortRowsByColumn(rows, {
indexOfColumnToSort: 1,
sortOrder: "ASC"
}));
-
I first sort the rows array based on the "group" key using
localeComparefor alphabetical sorting. -
Then, I map over the sorted rows and sort the data array within each group based on the specified column index using the existing
_sortFunction.