如何基于分组与列索引对扁平数组排序且保留原结构?
实现分组后按指定列排序的JavaScript函数
需求说明
现有一个包含分组信息的数组,当前的sortRowsByColumn函数仅能按指定列索引排序数组。需要更新该函数,实现先按group字段字母序排序,再对每个分组内的元素按指定列索引排序,同时不能修改原数组及数组的扁平结构,最终得到指定的排序结果。
现有代码
待排序数组
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"}, ];
现有排序函数
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; };
当前执行结果
[ {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"} ]
期望排序结果
[ {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"}, ]
修改后的排序函数
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)); // 先按group字母序排序,同组内再按指定列排序 return rowsCopy.sort((a, b) => { // 比较group字段的字母顺序 const groupCompare = a.group.localeCompare(b.group); if (groupCompare !== 0) { return groupCompare; } // 同组时,调用原排序逻辑按指定列排序 return _sortFunction(a, b, indexOfColumnToSort, sortOrder); }); } return rows; };
修改说明
- 分组排序逻辑:在
sort的回调函数中,先使用localeCompare比较两个元素的group字段,确保分组按字母顺序排列(localeCompare会返回负数、0或正数,对应a在b前、相等、a在b后)。 - 同组内排序:如果两个元素属于同一分组(
groupCompare === 0),再调用原有的_sortFunction按指定列索引和排序规则排序。 - 原数组保护:依然使用
JSON.parse(JSON.stringify(rows))创建数组副本,避免修改原数组。
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

