JavaScript多列同时排序实现:支持不同排序方向与类型
通用多列排序函数实现(无需预定义列信息)
我完全懂你的痛点——网上大部分多列排序的实现都硬编码了列名、排序方向或者数据类型,要是你需要一个能在运行时根据任意传入的排序规则动态处理的函数,这些方案就完全不适用了。下面咱们来构建一个通用的多列排序函数,调用前不需要知道任何列名或规则细节,只需要传入数据和排序规则列表就能自动完成多列排序。
核心思路
这个函数的核心逻辑是:根据传入的排序规则优先级依次比较数据项。我们先按照第一个规则比较两个数据项,如果它们在该规则下相等,就继续用下一个规则比较,直到找到能区分两者的规则,或者所有规则都比较完(此时认为两个数据项相等)。每个排序规则可以指定列名、排序方向,甚至自定义比较函数来处理特殊数据类型。
代码实现(JavaScript 版本)
function genericMultiSort(data, sortCriteria) { // 返回新的排序后的数组,避免修改原数据 return [...data].sort((a, b) => { // 按优先级遍历每个排序规则 for (const criterion of sortCriteria) { const { key, direction = 'asc', compareFn } = criterion; let comparisonResult; // 如果提供了自定义比较函数,优先使用它 if (compareFn) { comparisonResult = compareFn(a[key], b[key]); } else { // 默认的字符串/数字比较逻辑 if (a[key] < b[key]) comparisonResult = -1; else if (a[key] > b[key]) comparisonResult = 1; else comparisonResult = 0; } // 根据排序方向调整比较结果(降序则取反) if (direction === 'desc') { comparisonResult *= -1; } // 如果当前规则能区分两个项,直接返回结果 if (comparisonResult !== 0) { return comparisonResult; } } // 所有规则都无法区分,返回0表示相等 return 0; }); }
示例用法
假设我们有以下测试数据:
const testData = [ { 姓名: 'Alice', 年龄: 30, 分数: 85 }, { 姓名: 'Bob', 年龄: 25, 分数: 90 }, { 姓名: 'Charlie', 年龄: 30, 分数: 80 }, { 姓名: 'Alice', 年龄: 28, 分数: 95 }, ];
我们需要按照「姓名升序 → 年龄降序 → 分数升序」的规则排序,只需要传入对应的规则列表:
const sortRules = [ { key: '姓名', direction: 'asc' }, { key: '年龄', direction: 'desc' }, { key: '分数', direction: 'asc' }, ]; const sortedData = genericMultiSort(testData, sortRules);
排序后的结果如下:
[ { 姓名: 'Alice', 年龄: 30, 分数: 85 }, { 姓名: 'Alice', 年龄: 28, 分数: 95 }, { 姓名: 'Bob', 年龄: 25, 分数: 90 }, { 姓名: 'Charlie', 年龄: 30, 分数: 80 }, ];
扩展说明
- 自定义比较函数:如果需要处理日期、对象等特殊数据类型,只需要在排序规则中传入
compareFn即可。比如按日期字符串降序排序:
{ key: '入职日期', direction: 'desc', compareFn: (dateA, dateB) => new Date(dateB) - new Date(dateA) }
- 数据不可变性:函数会返回一个新的排序后的数组,不会修改原始数据,这是前端开发的最佳实践之一。
- 灵活性:你可以传入任意数量的排序规则,函数会按照规则列表的顺序依次处理,完全不需要提前知道列的数量或名称。
内容的提问来源于stack exchange,提问作者JoelCool
相关产品推荐
相关产品推荐

