【經典面試題】JavaScript陣列去重
阿新 • • 發佈:2019-02-11
題目
已知有如下一個陣列,要求實現一個去重方法:
var arr = ['aa', 'bb', 'cc', '', 1, 0, '1', 1, 'bb', null, undefined, null];
既然是面試題,肯定要考慮相容性和效率。
幾種實現
第一種實現
這是最容易想到的方法:
function unique1(array)
{
var result = [];
for(var i=0; i<array.length; i++)
{
if(result.indexOf(array[i]) < 0) result.push(array[i]);
}
return result;
}
var arr = ['aa', 'bb', 'cc', '', 1, 0, '1', 1, 'bb', null, undefined, null];
console.log(unique1(arr));
這種方法有2個缺點,一是效率問題,因為加上indexOf相當於是2重迴圈,二是indexOf的相容性問題。
第二種實現
遍歷陣列所有元素,如果發現其indexOf值等於遍歷的索引,則將其放到一個新陣列去,這種方法比第一種方法效率還要差,我估計一般都不會想到這個方法:
function unique2(array)
{
var result = [array[0] ];
for(var i=1; i<array.length; i++)
{
if(array.indexOf(array[i]) == i) result.push(array[i]);
}
return result;
}
var arr = ['aa', 'bb', 'cc', '', 1, 0, '1', 1, 'bb', null, undefined, null];
console.log(unique2(arr));
第三種實現
function unique3(array)
{
var result = [];
var hash = {};
for(var i=0; i<array.length; i++)
{
var key = (typeof array[i]) + array[i];
if(!hash[key])
{
result.push(array[i]);
hash[key] = true;
}
}
return result;
}
var arr = ['aa', 'bb', 'cc', '', 1, 0, '1', 1, 'bb', null, undefined, null];
console.log(unique3(arr));
這種實現方法中規中矩,不算最好也不算最差。
以上方法中之所以給key添加了型別字首,是因為要區分
'1'
和1
。
第四種實現
function unique4(array)
{
return Array.from(new Set(array));
}
var arr = ['aa', 'bb', 'cc', '', 1, 0, '1', 1, 'bb', null, undefined, null];
console.log(unique4(arr));
這種方法是評論裡網友提到的,使用了ES6種的Set,雖然效率很高,但是相容性大大滴有問題。
第五種實現
//TODO
速度比較
測試50萬長度的陣列,環境為Win10+Chrome50.0
:
var testArray = [];
for(var i=0; i<500000; i++)
{
testArray.push(parseInt(Math.random()*100));
}
function test(fn, name)
{
console.time(name);
fn(testArray);
console.timeEnd(name);
}
test(unique1, '第1種實現');
test(unique2, '第2種實現');
test(unique3, '第3種實現');
test(unique4, '第4種實現');
複製執行
結果比較驚訝:
第1種實現: 43.867ms
第2種實現: 234.370ms
第3種實現: 48.405ms
第4種實現: 31.978ms
第1種實現竟然比第3種略快一些,這個不知為何,可能是現代瀏覽器內部做了啥優化吧。