請分享你知道的陣列去除重複 (remove duplicates) 方法

2022年12月21日

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

在陣列中把重複的項目去除掉,是很常在實際工作中需要執行的操作。因此在 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 方法,只保留第一次出現的值,所以只要是第二次出現的,就會被篩掉,這能確保結果不會有重複的。程式碼如下:

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 上追蹤我們