數(shù)組去重是我們經(jīng)常在面試或者網(wǎng)上刷題時遇到的問題日熬,一般的想法是創(chuàng)建一個新的空數(shù)組,然后從原數(shù)組中一個個拿出元素,驗證在新數(shù)組中是否已有相同元素顾犹,如果沒有就置入倒庵;雖然我們知道這種方式是最low的。下面我們來看看這種最low的方案和優(yōu)化方案的區(qū)別炫刷。
首先我們先創(chuàng)建一個有十萬個擁有0-99整數(shù)數(shù)值和字符串元素的數(shù)組:
let i = 0
let arr = []
while(i++ < 100000) {
let one = ~~(Math.random()*100)
Math.random() > 0.5 && (one += '')
arr.push(one)
}
// 共有200種元素擎宝,創(chuàng)建100000個必然有重復(fù)
// [ '29', 60, 95, '45', '84', '6', 45, '50', '0', 91, '63', '75', 38, 58, 99, ... ]
首先是最簡單的但是性能很差的方案:
function uniqueArray(arr) {
let result = []
arr.forEach(item => {
!~result.indexOf(item) && result.push(item)
})
return result
}
這種方式明顯很耗性能,每個元素比對的時候都要進(jìn)行一次循環(huán)浑玛。我們用console.time打印看看這個函數(shù)處理的時間
console.time('uniqueArray')
let uniqueArr = uniqueArray(arr)
console.timeEnd('uniqueArray')
// 共花費時間
// uniqueArray: 51.007ms
上面的方案绍申,原數(shù)組有10萬個元素,在處理過程中就進(jìn)行了10萬次循環(huán)比對顾彰,造成了非常大的性能開銷极阅。
于是我們設(shè)想一種優(yōu)化的方案,使整個處理過程只需要進(jìn)行一次循環(huán):
function uniqueArray2(arr) {
let obj = {}, obj2 = {}, result = []
arr.forEach(item => {
if (item in obj) {
if (item !== obj[item] && !(item in obj2)) {
obj2[item] = item
result.push(item)
}
} else {
result.push(item)
obj[item] = item
}
})
return result
}
看看優(yōu)化方案的處理時間
console.time('uniqueArray2')
let uniqueArr2 = uniqueArray2(arr)
console.timeEnd('uniqueArray2')
// 共花費時間
// uniqueArray2: 8.142ms
可以看出性能優(yōu)化了不少涨享。
通過進(jìn)行多次不同元素個數(shù)處理對比筋搏,兩種方案的性能開銷大概8倍左右差距。
如果你有更優(yōu)化的解法厕隧,歡迎賜教奔脐。