JavaScript:陣列去重總結
阿新 • • 發佈:2021-07-20
陣列去重總結
1. 雙層迴圈
var array = [1, 1, '1', '1']; function unique(array) { // res用來儲存結果 var res = []; for (var i = 0, arrayLen = array.length; i < arrayLen; i++) { for (var j = 0, resLen = res.length; j < resLen; j++ ) { if (array[i] === res[j]) { break; } } // 如果array[i]是唯一的,那麼執行完迴圈,j等於resLen if (j === resLen) { res.push(array[i]) } } return res; } console.log(unique(array)); // [1, "1"]
2.indexOf
var array = [1, 1, '1']; function unique(array) { var res = []; for (var i = 0, len = array.length; i < len; i++) { var current = array[i]; if (res.indexOf(current) === -1) { res.push(current) } } return res; } console.log(unique(array));
3.排序後去重
試想我們先將要去重的陣列使用 sort 方法排序後,相同的值就會被排在一起,然後我們就可以只判斷當前元素與上一個元素是否相同,相同就說明重複,不相同就新增進 res,讓我們寫個 demo:
var array = [1, 1, '1']; function unique(array) { var res = []; var sortedArray = array.concat().sort(); var seen; for (var i = 0, len = sortedArray.length; i < len; i++) { // 如果是第一個元素或者相鄰的元素不相同 if (!i || seen !== sortedArray[i]) { res.push(sortedArray[i]) } seen = sortedArray[i]; } return res; } console.log(unique(array));
4.filter
var array = [1, 2, 1, 1, '1'];
function unique(array) {
var res = array.filter(function(item, index, array){
return array.indexOf(item) === index;
})
return res;
}
console.log(unique(array));
5.Object 鍵值對
這種方法是利用一個空的 Object 物件,我們把陣列的值存成 Object 的 key 值,比如 Object[value1] = true,在判斷另一個值的時候,如果 Object[value2]存在的話,就說明該值是重複的。示例程式碼如下:
var array = [1, 2, 1, 1, '1'];
function unique(array) {
var obj = {};
return array.filter(function(item, index, array){
return obj.hasOwnProperty(item) ? false : (obj[item] = true)
})
}
console.log(unique(array)); // [1, 2]
我們可以發現,是有問題的,因為 1 和 '1' 是不同的,但是這種方法會判斷為同一個值,這是因為物件的鍵值只能是字串,所以我們可以使用 typeof item + item 拼成字串作為 key 值來避免這個問題:
var array = [1, 2, 1, 1, '1'];
function unique(array) {
var obj = {};
return array.filter(function(item, index, array){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
console.log(unique(array)); // [1, 2, "1"]
然而,即便如此,我們依然無法正確區分出兩個物件,比如 {value: 1} 和 {value: 2},因為 typeof item + item 的結果都會是 object[object Object],不過我們可以使用 JSON.stringify 將物件序列化:
var array = [{value: 1}, {value: 1}, {value: 2}];
function unique(array) {
var obj = {};
return array.filter(function(item, index, array){
console.log(typeof item + JSON.stringify(item))
return obj.hasOwnProperty(typeof item + JSON.stringify(item)) ? false : (obj[typeof item + JSON.stringify(item)] = true)
})
}
console.log(unique(array)); // [{value: 1}, {value: 2}]
6.ES6
隨著 ES6 的到來,去重的方法又有了進展,比如我們可以使用 Set 和 Map 資料結構,以 Set 為例,ES6 提供了新的資料結構 Set。它類似於陣列,但是成員的值都是唯一的,沒有重複的值。
1.Set 方法
var array = [1, 2, 1, 1, '1'];
function unique(array) {
return Array.from(new Set(array));
}
console.log(unique(array)); // [1, 2, "1"]
甚至可以再簡化下:
function unique(array) {
return [...new Set(array)];
}
還可以再簡化下:
var unique = (a) => [...new Set(a)]
2.Map 方法
function unique (arr) {
const seen = new Map()
return arr.filter((a) => !seen.has(a) && seen.set(a, 1))
}
7.還有特殊型別的比較(這個一般用的比較少,甚至可以忽略)
直接放一個表:
總結
雖然去重的結果有所不同,但更重要的是讓我們知道在合適的場景要選擇合適的方法。、
參考文章:
JavaScript專題之陣列去重