数组去重的多种实现方案

在JavaScript开发中,数组去重是一个常见需求。本文将介绍多种实现数组去重的方法,帮助开发者根据不同的场景选择最适合的方案。

1. 使用Set数据结构(ES6)

ES6引入的Set数据结构天然具有去重特性,这是最简单高效的去重方法:

javascript 复制代码
const uniqueArray = [...new Set(array)];
// 或者
const uniqueArray = Array.from(new Set(array));

优点:代码简洁,性能优秀
缺点:无法处理特殊对象(如对象数组的去重)

2. 使用filter和indexOf

javascript 复制代码
const uniqueArray = array.filter((item, index) => {
  return array.indexOf(item) === index;
});

优点:兼容性好,支持ES5环境
缺点:对于大型数组性能较差,时间复杂度O(n²)

3. 使用reduce方法

javascript 复制代码
const uniqueArray = array.reduce((acc, current) => {
  if (!acc.includes(current)) {
    acc.push(current);
  }
  return acc;
}, []);

优点:函数式编程风格,可读性好
缺点:性能中等,对于大型数组不如Set高效

4. 使用对象键值对

javascript 复制代码
const obj = {};
const uniqueArray = [];
for (let item of array) {
  if (!obj[item]) {
    uniqueArray.push(item);
    obj[item] = true;
  }
}

优点:性能较好,时间复杂度O(n)
缺点:会将所有元素转为字符串,不适合对象数组

5. 双层循环(传统方法)

javascript 复制代码
const uniqueArray = [];
for (let i = 0; i < array.length; i++) {
  let isDuplicate = false;
  for (let j = 0; j < uniqueArray.length; j++) {
    if (array[i] === uniqueArray[j]) {
      isDuplicate = true;
      break;
    }
  }
  if (!isDuplicate) {
    uniqueArray.push(array[i]);
  }
}

优点:兼容性最好,无需任何ES6特性
缺点:性能最差,时间复杂度O(n²)

6. 针对对象数组的去重方案

对于对象数组,上述方法可能无法直接使用,需要特殊处理:

javascript 复制代码
const uniqueObjectArray = array.reduce((acc, current) => {
  const isDuplicate = acc.some(item => 
    JSON.stringify(item) === JSON.stringify(current)
  );
  if (!isDuplicate) {
    acc.push(current);
  }
  return acc;
}, []);

注意:这种方法性能较差,且JSON.stringify可能无法处理循环引用

性能比较

在大多数现代JavaScript引擎中,性能从高到低排序大致为:

  1. Set方法
  2. 对象键值对方法
  3. reduce方法
  4. filter+indexOf方法
  5. 双层循环方法

总结

选择哪种去重方法取决于:

  • 运行环境(是否需要支持旧浏览器)
  • 数组大小(性能考虑)
  • 数组元素类型(基本类型还是对象)

对于现代浏览器环境,优先推荐使用Set方法;如果需要兼容旧环境,可以考虑reduce或filter方法;对于对象数组,则需要根据具体情况定制去重逻辑。