JavaScript篇:JavaScript数组排序的实战心得:从基础到高阶

15 阅读4分钟

🎓 作者简介前端领域优质创作者

🚪 资源导航: 传送门=>

🎬 个人主页:  江城开朗的豌豆

🌐 个人网站:    江城开朗的豌豆 🌍

📧 个人邮箱: YANG_TAO_WEB@163.com 📩

💬 个人微信:     y_t_t_t_ 📱

📌  座  右 铭: 生活就像心电图,一帆风顺就证明你挂了 💔

👥 QQ群:  906392632 (前端技术交流群) 💬

作为前端开发者的最近在项目中遇到了一个有趣的排序需求:需要将一个包含员工信息的数组按照年龄、姓名等多条件排序。这让他重新审视了JavaScript中数组排序的各种方法。今天,我们就来深入探讨数组排序的奥秘。

基础篇:sort()方法入门

JavaScript数组自带的sort()方法是最基础的排序方式,但它的行为可能会让初学者感到困惑:

const numbers = [10, 5, 8, 1, 7];
numbers.sort();
console.log(numbers); // [1, 10, 5, 7, 8] - 咦?这不对劲!

第一次使用时也踩了这个坑。原来,sort()默认将元素转换为字符串后按Unicode码点排序。要实现真正的数值排序,需要传入比较函数:

const numbers = [10, 5, 8, 1, 7];
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 5, 7, 8, 10] - 这才对嘛!

对象数组排序实战

实际开发中,我们经常需要对对象数组进行排序。比如需要处理的员工数据:

const employees = [
  { name: '杨涛', age: 28, salary: 15000 },
  { name: '李四', age: 25, salary: 12000 },
  { name: '王五', age: 30, salary: 18000 }
];

// 按年龄升序
employees.sort((a, b) => a.age - b.age);
console.log('按年龄排序:', employees);

// 按薪资降序
employees.sort((a, b) => b.salary - a.salary);
console.log('按薪资排序:', employees);

多条件排序技巧

当单一条件无法满足需求时,我们需要多条件排序。比如先按年龄升序,年龄相同再按薪资降序:

employees.sort((a, b) => {
  if (a.age !== b.age) {
    return a.age - b.age; // 年龄不同,按年龄升序
  }
  return b.salary - a.salary; // 年龄相同,按薪资降序
});
console.log('多条件排序:', employees);

字符串排序的注意事项

对字符串排序时,直接使用sort()会有大小写敏感的问题:

const names = ['杨涛', 'alice', 'Bob', '张伟'];
names.sort();
console.log(names); // ['Bob', 'alice', '张伟', '杨涛'] - 不符合预期

发现需要使用localeCompare()才能实现更合理的排序:

names.sort((a, b) => a.localeCompare(b, 'zh'));
console.log('中文排序:', names); // ['alice', 'Bob', '杨涛', '张伟']

高级技巧:随机排序

有时候我们需要打乱数组顺序,比如开发抽奖功能时:

const participants = ['杨涛', '李四', '王五', '赵六'];
participants.sort(() => Math.random() - 0.5);
console.log('随机排序:', participants);

不过后来了解到,这种方法并不是真正的公平随机,对于严肃的随机需求应该使用Fisher-Yates洗牌算法:

function shuffle(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

console.log('公平随机:', shuffle(participants));

性能优化:大规模数据排序

当处理大规模数据时,sort()的性能就显得尤为重要。杨涛在测试中发现:

// 生成10万条测试数据
const bigData = Array.from({ length: 100000 }, () => 
  Math.floor(Math.random() * 1000000));

// 普通排序
console.time('普通排序');
bigData.sort((a, b) => a - b);
console.timeEnd('普通排序'); // 约50ms

// 优化后的排序(对已部分排序的数据更高效)
console.time('优化排序');
bigData.sort((a, b) => {
  if (a < b) return -1;
  if (a > b) return 1;
  return 0;
});
console.timeEnd('优化排序'); // 约30ms

实战案例:表格排序组件

结合这些知识,实现了一个可复用的表格排序组件:

function sortTable(data, key, direction = 'asc') {
  return [...data].sort((a, b) => {
    const valueA = a[key];
    const valueB = b[key];
    
    if (typeof valueA === 'number' && typeof valueB === 'number') {
      return direction === 'asc' ? valueA - valueB : valueB - valueA;
    }
    
    return direction === 'asc' 
      ? String(valueA).localeCompare(String(valueB))
      : String(valueB).localeCompare(String(valueA));
  });
}

// 使用示例
const sortedEmployees = sortTable(employees, 'name', 'desc');
console.log('按姓名降序:', sortedEmployees);

总结与最佳实践

经过这些实践,总结出数组排序的几个要点:

  1. 永远记住sort()会修改原数组,必要时先创建副本
  2. 对数值排序一定要提供比较函数
  3. 字符串排序考虑使用localeCompare()以获得更好的语言支持
  4. 多条件排序时,按优先级逐个比较
  5. 大规模数据排序要注意性能优化

"排序看似简单,但魔鬼藏在细节中。"这是在项目复盘时的感悟。掌握这些技巧后,你的代码将更加健壮高效。

希望这篇文章能帮助你,在数组排序上游刃有余。下次遇到排序需求时,不妨多思考一下是否有更优雅的实现方式。