请分享你知道的数组去除重复 (remove duplicates) 方法

2022年12月21日

💎 加入 E+ 成長計畫 與超過 350+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

在数组中把重复的项目去除掉,是很常在实际工作中需要执行的操作。因此在 JavaScript 面试时,也很常会被问。这种题目通常会要当场手写,所以假如你不太确定要怎么手写去除重复,一定要在面试前多练习几次。

数组去除重复题目长什么样?

数组去除重复的面试题,通常会像下面这样,给一个数组,里面有重复的数字,并要求写一个 removeDuplicate 函式,输入是原始数组,输出是去除重复数字的数组。


const originalArr = [9,1,2,2,3,4,2,4,8,1,9]

function removeDuplicate(array){
...
}

const ans = removeDuplicate(originalArr);
console.log(ans) // [9,1,2,3,4,8]

数组去重复其实有很多种做法,以下会列出 4 种常见做法。在面试考手写题时,数组去重复有可能是单独一种题型,或者是在解手写题时一开始需要将数组进行去重复的操作。建议询问面试官题目的需求、主动跟面试官讨论期望的解法,再选择要使用哪一种解法。

四种解法

解法一:使用 Set 去重复

Set 的资料格式与用法类似于Array,但有一特色是Set 中只能储存任何资料的唯一值,因此可以先将Array 转为Set,此时重复的值会被移除,再将Set 转为Array代码如下:

function removeDuplicate(arr) {
  return Array.from(new Set(arr));
}

// 也可以利用 spread syntax 更简化代码
function removeDuplicate(arr) {
  return [...new Set(arr)];
}

let arr = [1, 2, 3, 2, 3, 8];
let arrAfter = removeDuplicate(arr);

console.log(arr1After); // [1, 2, 3, 8]

解法二: filter 搭配 indexOf

此解法先用 array 的filter 方法,搭配[indexOf](https://developer .mzilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) 方法,只保留第一次出现的值,所以只要是第二次出现的,就会被筛掉,这能确保结果不会有重复的。 代码如下:

function removeDuplicate(arr) {
  // indexOf 会回传在这个 array 等同于此值第一个 item 的 index,
  // 所以如果 indexOf 回传的 index 相等于目前 filter 到的值,
  // 则代表该值是第一次出现,我们保留起来,
  // 反之,如果 index 不等于,则代表此 array 中前面位置已经出现过,所以就 filter 掉。
  return arr.filter((item, index, array) => array.indexOf(item) === index);
}

let arr = [1, 2, 3, 2, 3, 8];
let arrAfter = removeDuplicate(arr);

console.log(arrAfter); // [1, 2, 3, 8]

解法三: 双层 for loop

双层 for loop 是一种暴力解。依序遍历整个 array,再透过第二层 for loop 找出重复的值将其移除。 代码如下:

function removeDuplicate(arr) {
  // 第一层 for loop,i 从 index 0 开始,到 arr 最后
  for (let i = 0, len = arr.length; i < len; i++) {
    // 第二层 for loop,j 从 i + 1 开始,要检查值是否重复
    for (let j = i + 1; j < len; j++) {
      // 如果值重复,则透过 splice 方法将 j 位置的值从 arr 去除
      if (arr[i] == arr[j]) {
        arr.splice(j, 1);
        // 移除重复的值之后,arr length 长度会需要减 1
        len--;
        // j 位置的值被移除,因此 j index 也要减 1
        j--;
      }
    }
  }
  return arr;
}

let arr = [1, 2, 3, 2, 3, 8];
let arrAfter = removeDuplicate(arr);

console.log(arrAfter); // [1, 2, 3, 8]

解法四: 透过 object 或 Map 储存以遍历过的项目

我们可以透过 object 或 Map 来储存已经遍历过的项目,来找出是否已存在数组当中,如果还不在,那就放进要输出的数组;如果已经在了,就不再放入,这样一来能确保数组中没有重复的值。 代码如下:

function removeDuplicate(arr) {
  let seen = {};
  let newArray = [];

  // 遍历过原本的数组
  for (let item of arr) {
    // 判断当前被遍历到的项目是否已经放入过
    if (seen[item] !== true) {
      newArray.push(item); // 如果还没,则放入要被输出的新数组
      seen[item] = true; // 这时纪录一下这个项目已经被放入,下次就不会再被放入
    }
  }
  return newArray;
}

let arr = [1, 2, 3, 2, 3, 8];
let arrAfter = removeDuplicate(arr);

console.log(arrAfter); // [1, 2, 3, 8]
🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們