
本文介绍一种高效、可复用的 JavaScript 数组排序方案:先按 group 字段字母序分组排序,再在每组内按指定列索引(如 data[1].value)升序或降序排序,最终合并为原结构的扁平数组,不改变原始数据。
本文介绍一种高效、可复用的 javascript 数组排序方案:先按 `group` 字段字母序分组排序,再在每组内按指定列索引(如 `data[1].value`)升序或降序排序,最终合并为原结构的扁平数组,不改变原始数据。
在实际表格或数据看板开发中,常需对具有分组语义的扁平数组进行多级稳定排序:既要保证相同 group 的项相邻(一级排序),又要在组内依据具体数值字段(如第二列 data[1].value)精细排序(二级排序)。关键约束是:不能展开/嵌套结构,必须维持原始扁平数组形态。
实现该需求的核心思路是三步法:
-
分组聚合:按
group键将原数组划分为多个子数组; -
组内排序:对每个子数组调用原有
_sortFunction进行列值排序; -
有序合并:先对分组键(
group名)做字母序排序,再按序拼接各子数组。
以下是优化后的完整实现(含健壮性增强与注释):
const _sortFunction = (a, b, columnIndex, sortOrder) => {
// 安全访问 data[columnIndex],避免 undefined 报错
const aVal = a?.data?.[columnIndex]?.value;
const bVal = b?.data?.[columnIndex]?.value;
if (aVal === bVal) return 0;
if (sortOrder === 'ASC') return aVal < bVal ? -1 : 1;
if (sortOrder === 'DESC') return aVal > bVal ? -1 : 1;
return 0;
};
const sortRowsByColumn = (rows, sortProps) => {
if (!Array.isArray(rows) || !sortProps || typeof sortProps !== 'object') {
return rows;
}
const { indexOfColumnToSort, sortOrder } = sortProps;
// 输入校验:列索引必须为有效数字,排序方向必须合法
if (typeof indexOfColumnToSort !== 'number' ||
!['ASC', 'DESC'].includes(sortOrder?.toUpperCase())) {
return [...rows]; // 返回浅拷贝,避免副作用
}
// 步骤1:按 group 键分组(使用 reduce 构建对象映射)
const grouped = rows.reduce((acc, row) => {
const key = row?.group ?? '';
if (!acc[key]) acc[key] = [];
acc[key].push({ ...row }); // 深拷贝每项,确保不污染原数据
return acc;
}, {});
// 步骤2:对每个分组内部排序
Object.values(grouped).forEach(groupArray => {
groupArray.sort((a, b) =>
_sortFunction(a, b, indexOfColumnToSort, sortOrder.toUpperCase())
);
});
// 步骤3:按键名(group)字母序排序,并扁平化合并
return Object.keys(grouped)
.sort((a, b) => a.localeCompare(b)) // 更可靠的字符串比较
.reduce((acc, groupKey) => acc.concat(grouped[groupKey]), []);
};✅ 使用示例:
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" }));
// 输出符合预期的扁平数组:Elephant 组内按 B/D 值升序,Lion 组内按 H/N 值升序,组间按字母序排列⚠️ 注意事项:
- 本方案不修改原始
rows数组,所有操作基于副本; - 使用
localeCompare()替代>/进行字符串排序,支持国际化; - 对
data和value层级做了空值防护,提升鲁棒性; - 若需支持多列复合排序(如先按 group,再按 data[0].value,最后 data[1].value),可扩展
_sortFunction为数组参数并迭代比较。
该模式适用于 React/Vue 表格组件、数据导出逻辑及任何需要“分组内精细化排序”的场景,兼顾可读性、性能与工程健壮性。

















