JavaScript的數組去重在我們的日常開發中可謂是非常常見的問題,那麼問題來了?大家都喜歡用什麼方法解決數組去重問題呢?
1、對象去重法
我最開始學習的JS的時候使用的一種方法,這種方法可能初學者最先想到的解法,因爲根據object對象的屬性如果相同則會覆蓋,從而能夠進行判斷使用存在相同元素。
const unique = (arr) => {
let map = {};
let res = [];
for (let i = 0; i < arr.length; i++) {
if (!map[arr[i]]) {
map[arr[i]] = 1;
res.push(arr[i]);
}
}
return res;
}
2、使用indexOf去重
indexOf去重的方法原理也很簡單,只是根據數組的下標進行判斷,如果存的數組中存在這個元素說明該元素已經存在即重複,所以不需要進行存取。
const unique = (arr) => {
let res = [];
for (let i = 0; i < arr.length; i++) {
if (res.indexOf(arr[i]) < 0) {
res.push(arr[i]);
}
}
return res;
}
3、使用 indexOf 和 索引值進行判斷
也是用到indexOf進行判斷,根據indexOf取得下標與當前的索引值進行判斷,如果下標值與索引值不相等,那麼說明存在了重複元素,去掉即可。
const unique = (arr) => {
let res = [];
for (let i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) == i) {
res.push(arr[i]);
}
}
return res;
}
4、使用lastIndexOf 和 索引值進行判斷
原理和上一個類似,但是使用方法相反
const unique = (arr) => {
let res = [];
for (let i = 0; i < arr.length; i++) {
if (arr.lastIndexOf(arr[i]) == i) {
res.push(arr[i]);
}
}
return res;
}
5、循環對比兩兩數
使用一層循環進行判斷相鄰兩個數是否重複(提前對數組進行排序),如果重複則去掉
const unique = (arr) => {
let res = [];
// 需要先排序
arr.sort((a, b) => a - b);
res[0] = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i - 1]) {
res.push(arr[i]);
}
}
return res;
}
6、使用數組的includes方法(ES6新方法)
使用includes方法在暫存的數組中進行判斷是否存在,如果存在則不需要添加
const unique = (arr) => {
let res = [];
for (let i = 0; i < arr.length; i++) {
if (!res.includes(arr[i])) {
res.push(arr[i]);
}
}
return res;
}
7、使用數組的filter函數+indexOf判斷
運用數組的filter方法進行遍歷,然後也是對indexOf的索引值進行判斷
const unique = (arr) => {
return arr.filter((item, index, _arr) => {
return _arr.indexOf(item) === index;
})
}
8、splice去重
通過數組的splice方法直接在原數組上進行修改,需要注意的是如果不需要改變原數組的話那麼需要進行一份拷貝,然後在是要該方法即可
const unique = (arr) => {
arr.sort((a, b) => a - b);
for (let i = 0; i < arr.length - 1; i++) {
if (arr[i + 1] === arr[i]) {
arr.splice(i, 1);
i--;
}
}
return arr;
}
9、使用Map數據結構去重
根據Map的不可重複性可以進行去重操作,但是就是需要一定的內存損耗。
const unique = (arr) => {
let res = [];
let map = new Map();
for (let i = 0; i < arr.length; i++) {
if (!map.has(arr[i])) {
res.push(arr[i]);
map.set(arr[i], true);
}
}
return res;
}
10、使用reduce去重(ES6新方法)
代碼簡潔,如果不熟悉reduce方法的小夥伴可以去看看學學這個方法的使用,這個方法如果用的好的話確實有很大用處。
const unique = (arr) => {
return arr.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
}
11、使用Set數據結構去重
這個可能是學習了ES6之後的常用去重方法了,簡單便捷,易於使用,代碼量小
const unique = (arr) => {
return [...new Set(arr)];
}
如果需要去重複雜數組的話如這種結構也可以使用Set結構進行去重
let arr = [1, {a: 1, b: 2}, [1, 2, 3], {a: 1, b: 2}, [1, 2, 3]
const unique = (arr) => {
return [...new Set(arr.map(item => JSON.stringify(item)))].map(item => JSON.parse(item));
}
以上代碼均只適用於簡單的數組去重操作
寫在最後
因爲方法比較多,所以大家可以根據不同的場景來使用不同的方法,比如常常需要考慮的是時間複雜度和空間複雜度。根據不同的需要進行選擇,以時間換空間還是以空間換時間。