问题:如何实现数组去重?

数组去重是前端面试中的高频题目,本文汇总多种实现方案及适用场景。


核心方案

方法时间复杂度空间复杂度特点
SetO(n)O(n)最简洁,推荐
filter + indexOfO(n²)O(n)语义清晰
reduceO(n²)O(n)函数式风格
sort + filterO(n log n)O(n)适合有序数组
MapO(n)O(n)支持复杂类型

具体实现

1. Set(推荐)

// 最简洁
const arr = [1, 2, 2, 3, 3, 3];
const unique = [...new Set(arr)];
// [1, 2, 3]
 
// 或者
const unique = Array.from(new Set(arr));

原理:Set 自动去重

2. filter + indexOf

const unique = arr.filter((item, index) => {
  return arr.indexOf(item) === index;
});

原理:保留首次出现的元素,双层循环

3. reduce

const unique = arr.reduce((prev, cur) => {
  return prev.includes(cur) ? prev : [...prev, cur];
}, []);

原理:累积唯一元素,每次 includes 也是 O(n)

4. sort + filter

const unique = arr.slice().sort().filter((item, index, arr) => {
  return !index || item !== arr[index - 1];
});

原理:排序后相同元素相邻,去除相邻重复

5. Map(支持复杂类型)

function unique(arr) {
  const map = new Map();
  return arr.filter(item => !map.has(item) && map.set(item, true));
}

原理:Map 的 key 可以是对象


方案对比

方案优点缺点
Set代码简洁,性能好不适合对象数组
filter+indexOf语义清晰O(n²) 性能差
reduce可链式操作代码稍长
sort适合有序数组会改变原数组顺序
Map支持对象去重代码稍复杂

面试追问

Q:如何去除对象数组中的重复项?

const arr = [{a:1}, {a:1}, {a:2}];
const unique = [...new Map(arr.map(item => [JSON.stringify(item), item])).values()];

Q:如何保留最后一个重复项而不是第一个?

const unique = arr.filter((item, index) => {
  return arr.lastIndexOf(item) === index;
});

知识图谱


参考延伸

  • JavaScript 数组去重方法汇总
  • LeetCode 26. Remove Duplicates from Sorted Array