數組去重的性能比較

數組去重是面試常考點,可是這些方法的性能之間的比較,你知道嗎?下面來比較一下

方法1:Array.filter()+indexOf()

 使用 ES6 中的 Array.filter() 遍歷數組,並結合 indexOf 來排除重複項

let arr1 = Array.from(new Array(100000), (x, index) => { return index; }); let arr2 = Array.from(new Array(50000), (x, index) => { return index + index; }); let start = new Date().getTime(); console.log('數組開始去重');
console.log('去重後的長度', distinct1(arr1, arr2).length); 
let end
= new Date().getTime();
console.log(
'耗時', end - start);
// 數組開始去重 
// distinct.js:11 去重後的長度 100000
// distinct.js:14 耗時 9523
// 方法1:Array.filter()+indexOf()
function distinct1(a, b) {
  // 數組去重
  let arr = a.concat(b);
  return arr.filter((item, index) => {
    return arr.indexOf(item) === index;
  });
}

方法2:雙重for循環

外層循環遍歷元素,內層循環檢查是否重複
當有重複值的時候,能夠使用 push(),也能夠使用 splice()
let arr1 = Array.from(new Array(100000), (x, index) => { return index; }); let arr2 = Array.from(new Array(50000), (x, index) => { return index + index; }); let start = new Date().getTime(); console.log('數組開始去重'); console.log('去重後的長度', distinct2(arr1, arr2).length); let end = new Date().getTime(); console.log('耗時', end - start); // 方法2:雙重for循環 // 外層循環遍歷元素,內層循環檢查是否重複 // 當有重複值的時候,能夠使用 push(),也能夠使用 splice()

function distinct2(a, b) { let arr = a.concat(b); for (let i = 0, len = arr.length; i < len; i++) { for (let j = i + 1; j < len; j++) { if (arr[i] === arr[j]) { arr.splice(j, 1); // splice能夠改變數組長度,因此數組長度len和j的下標減一
        len--; j--; } } } return arr; } // 數組開始去重 // 去重後的長度 100000 // 耗時 22534

方法3:雙重for循環升級版

外層用 for...of 語句替換 for 循環,把內層循環改成 includes()
先建立一個空數組,當 includes() 返回 false 的時候,就將該元素 push 到空數組中
 相似的,還能夠用 indexOf() 來替代 includes()
let arr1 = Array.from(new Array(100000), (x, index) => { return index; }); let arr2 = Array.from(new Array(50000), (x, index) => { return index + index; }); let start = new Date().getTime(); console.log('數組開始去重'); console.log('去重後的長度', distinct3(arr1, arr2).length); let end = new Date().getTime(); console.log('耗時', end - start); // 方法3:雙重for循環升級版 // 外層用 for...of 語句替換 for 循環,把內層循環改成 includes() // 先建立一個空數組,當 includes() 返回 false 的時候,就將該元素 push 到空數組中 // 相似的,還能夠用 indexOf() 來替代 includes()

function distinct3(a, b) { let arr = a.concat(b); let result = []; for (const i of arr) { // 若是result中沒有i,就把i push進去數組result !result.includes(i) && result.push(i); } return result; } // 數組開始去重 // 去重後的長度 100000 // 耗時 9851
 這種方法和 filter + indexOf 挺相似
只是把 filter() 的內部邏輯用 for 循環實現出來,再把 indexOf 換爲 includes
因此時長上也比較接近

方法4:Array.sort()

首先使用 sort() 將數組進行排序
而後比較相鄰元素是否相等,從而排除重複項
let arr1 = Array.from(new Array(100000), (x, index) => { return index; }); let arr2 = Array.from(new Array(50000), (x, index) => { return index + index; }); let start = new Date().getTime(); console.log('數組開始去重'); console.log('去重後的長度', distinct4(arr1, arr2).length); let end = new Date().getTime(); console.log('耗時', end - start); // 方法4:Array.sort() // 首先使用 sort() 將數組進行排序 // 而後比較相鄰元素是否相等,從而排除重複項
function distinct4(a, b) { let arr = a.concat(b);  arr = arr.sort(); let result = [arr[0]]; // result中保存排序後的數組的第一項
  for (let i = 0, len = arr.length; i < len; i++) { // 若是相鄰兩項元素不等,則push進去數組result
    arr[i] !== arr[i - 1] && result.push(arr[i]); } return result; } // 數組開始去重 // 去重後的長度 100001 // 耗時 95 // 這種方法只作了一次排序和一次循環,因此效率會比上面的方法都要高

方法5:new Set()

 ES6 新增了 Set 這一數據結構,相似於數組,但 Set 的成員具備惟一性
 基於這一特性,就很是適合用來作數組去重了
let arr1 = Array.from(new Array(100000), (x, index) => { return index; }); let arr2 = Array.from(new Array(50000), (x, index) => { return index + index; }); let start = new Date().getTime(); console.log('數組開始去重'); console.log('去重後的長度', distinct5(arr1, arr2).length); let end = new Date().getTime(); console.log('耗時', end - start); // 方法5:new Set() // ES6 新增了 Set 這一數據結構,相似於數組,但 Set 的成員具備惟一性 // 基於這一特性,就很是適合用來作數組去重了

function distinct5(a, b) { // let arr = a.concat(b);
  return Array.from(new Set([...a, ...b])); } // 數組開始去重 // 去重後的長度 100000 // 耗時 37

// function distinct5(a, b) { // let arr = a.concat(b); // return Array.from(new Set(arr)); // } // 數組開始去重 // 去重後的長度 100000 // 耗時 35

方法6:for...of + Object

首先建立一個空對象,而後用 for 循環遍歷
利用對象的屬性不會重複這一特性,校驗數組元素是否重複
let arr1 = Array.from(new Array(1000000), (x, index) => { return index; }); let arr2 = Array.from(new Array(50000), (x, index) => { return index + index; }); let start = new Date().getTime(); console.log('數組開始去重'); console.log('去重後的長度', distinct6(arr1, arr2).length); let end = new Date().getTime(); console.log('耗時', end - start); // 方法6:for...of + Object // 首先建立一個空對象,而後用 for 循環遍歷 // 利用對象的屬性不會重複這一特性,校驗數組元素是否重複

function distinct6(a, b) { let arr = a.concat(b); let result = [];  let obj = {}; for (const i of arr) { if (!obj[i]) { result.push(i); obj[i] = 1; } } return result; } // 數組開始去重 // 去重後的長度 100000 // 耗時 27
// 速度很是快,ni new Set()還快
// 150w數據須要多長時間呢? // 數組開始去重 // 去重後的長度 1000000 // 耗時 246 OMG,簡直不敢相信

因此,性能比較好的方法,應該是html

方法4:Array.sort()(好)

方法5:new Set()(較好)

方法6:for...of + Object(優)

 

本文參考:https://www.cnblogs.com/wisewrong/p/9642264.html 僅供學習面試

相關文章
相關標籤/搜索