1. 程式人生 > >【經典面試題】JavaScript陣列去重

【經典面試題】JavaScript陣列去重

題目

已知有如下一個陣列,要求實現一個去重方法:

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種略快一些,這個不知為何,可能是現代瀏覽器內部做了啥優化吧。