請分享你知道的陣列去除重複 (remove duplicates) 方法
2022年12月21日
💎 加入 E+ 成長計畫 如果你喜歡我們的內容,歡迎加入 E+,獲得更多深入的軟體前後端內容
在陣列中把重複的項目去除掉,是很常在實際工作中需要執行的操作。因此在 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]