joken-前端工程师

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::
  394 随笔 :: 39 文章 :: 8 评论 :: 20万 阅读
/**
 * 多级排序函数
 * @param {Array} arr - 需要排序的数组
 * @param {Array} sortRules - 排序规则数组
 * @returns {Array} - 排序后的数组
 */
function multiLevelSort(arr, sortRules) {
    return arr.sort((a, b) => {
        // 遍历每个排序规则
        for (let rule of sortRules) {
            const { key, order = 'asc', customOrder } = rule;
            const valueA = a[key];
            const valueB = b[key];

            // 如果有自定义排序顺序
            if (customOrder) {
                const indexA = customOrder.indexOf(valueA);
                const indexB = customOrder.indexOf(valueB);
                
                // 处理值不在自定义顺序中的情况
                if (indexA === -1 && indexB === -1) continue;
                if (indexA === -1) return 1;
                if (indexB === -1) return -1;
                if (indexA !== indexB) return indexA - indexB;
            } 
            // 常规升序降序排序
            else {
                if (valueA === valueB) continue;
                if (valueA === undefined) return 1;
                if (valueB === undefined) return -1;
                
                const multiplier = order === 'desc' ? -1 : 1;
                if (typeof valueA === 'string' && typeof valueB === 'string') {
                    return valueA.localeCompare(valueB) * multiplier;
                }
                return (valueA - valueB) * multiplier;
            }
        }
        return 0; // 如果所有规则都相等
    });
}

// 使用示例
const data = [
    { name: 'Alice', age: 25, status: 'active' },
    { name: 'Bob', age: 30, status: 'inactive' },
    { name: 'Charlie', age: 25, status: 'pending' },
    { name: 'David', age: 35, status: 'active' },
];

// 示例1:简单多级排序(年龄降序,名字升序)
const simpleSort = multiLevelSort([...data], [
    { key: 'age', order: 'desc' },
    { key: 'name', order: 'asc' }
]);
console.log('简单多级排序:');
console.log(simpleSort);

// 示例2:带自定义顺序的排序(状态自定义顺序,年龄降序)
const customSort = multiLevelSort([...data], [
    { 
        key: 'status', 
        customOrder: ['active', 'pending', 'inactive'] // 自定义状态排序顺序
    },
    { key: 'age', order: 'desc' }
]);
console.log('\n带自定义顺序的排序:');
console.log(customSort);

// 示例3:混合排序(状态自定义,年龄降序,名字升序)
const mixedSort = multiLevelSort([...data], [
    { 
        key: 'status', 
        customOrder: ['active', 'pending', 'inactive'] 
    },
    { key: 'age', order: 'desc' },
    { key: 'name', order: 'asc' }
]);
console.log('\n混合排序:');
console.log(mixedSort);

这个实现具有以下特点:

  1. 参数说明

    • arr: 需要排序的数组(会返回新数组,原数组不变)
    • sortRules: 排序规则数组,每个规则对象包含:
      • key: 要排序的字段名
      • order: 'asc'(升序,默认)或 'desc'(降序)
      • customOrder: 可选,自定义值的排序顺序数组
  2. 功能特性

    • 支持多级排序,按规则顺序依次比较
    • 支持自定义值顺序(如特定状态的优先级)
    • 支持升序/降序切换
    • 支持字符串和数字排序
    • 处理 undefined 值的情况
    • 相同值时继续检查下一级规则
  3. 运行结果示例

// 简单多级排序:
[
    { name: 'David', age: 35, status: 'active' },
    { name: 'Bob', age: 30, status: 'inactive' },
    { name: 'Alice', age: 25, status: 'active' },
    { name: 'Charlie', age: 25, status: 'pending' }
]

// 带自定义顺序的排序:
[
    { name: 'David', age: 35, status: 'active' },
    { name: 'Alice', age: 25, status: 'active' },
    { name: 'Charlie', age: 25, status: 'pending' },
    { name: 'Bob', age: 30, status: 'inactive' }
]

// 混合排序:
[
    { name: 'David', age: 35, status: 'active' },
    { name: 'Alice', age: 25, status: 'active' },
    { name: 'Charlie', age: 25, status: 'pending' },
    { name: 'Bob', age: 30, status: 'inactive' }
]
  1. 使用注意
    • 输入数组使用 [...data] 创建副本,避免修改原数组
    • 字符串比较使用 localeCompare 以支持多语言
    • 未定义的 customOrder 值会被排到后面
    • 如果所有规则都相等,返回原顺序
posted on   joken1310  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示