您的位置:首页 > 职场人生

js面试题:关于数组去重的四种方法总结

2013-04-05 15:58 816 查看
在web前端面试题中,经常会出现这样一道题目:“请写一段函数,剔除数组中重复的元素。”

于是今天认真想了想,出了两个方案,性能方面都不理想,于是在大漠的qq群里面请教,网友Dino出了个方案,经过测试,性能很好,于是一起总结下:

测试环境:window 7 -firefox 19--firebug

方案一:obj属性判断除重法--性能最好,推荐!(虽然多了个obj,但比后面两个方案快多了)

var aRandomNumberItems = function (n){
var result = [];
for (var i = 0;i < n; i++){
var nRandom = Math.ceil(Math.random()*50);
result.push(nRandom);
}
return result;
};
var aRandomNumberItem1 = aRandomNumberItems(50000);
console.time('time3');
Array.prototype.distinct3 = function () {
var arr = [],
obj = {},
len = this.length,
result;
for (var i = 0; i < len; i++) {
result = this[i];
if (!obj[result]) {
obj[result] = '1';
arr.push(result);
}
}
return arr;

}

aRandomNumberItem1.distinct3();

console.timeEnd('time3');//结果为4ms
}


方案二:在方案一的基础上把函数内的数组for()循环修改为了forEach() 循环,反而效率下降了。而且IE6、7、8不支持forEach()函数,尽管我们可以给他们打补丁来实现兼容

var aRandomNumberItems = function (n){
var result = [];
for (var i = 0;i < n; i++){
var nRandom = Math.ceil(Math.random()*50);
result.push(nRandom);
}
return result;
};
var aRandomNumberItem1 = aRandomNumberItems(50000);
console.time('time');
Array.prototype.distinct = function () {
var arr = [],
obj = {};
this.forEach(function (value,index){
if (!obj[value]){
obj[value] = 1;
arr.push(value);
}
})

return arr;

}

aRandomNumberItem1.distinct();

console.timeEnd('time');//结果为28ms


方案三:sort排序循环比对法---性能不太好(sort()性能不太好,循环比对次数也多,整体慢)

var aRandomNumberItems = function (n){
var result = [];
for (var i = 0;i < n; i++){
var nRandom = Math.ceil(Math.random()*50);
result.push(nRandom);
}
return result;
};
var aRandomNumberItem1 = aRandomNumberItems(50000);
console.time('time1')
Array.prototype.distinct1 = function () {
this.sort(function (a,b) {
return a-b;
})

for (var i = 0; i < this.length-1; i++){
if (this[i] === this[i+1]){
this.splice(i+1,1);
i--;
}
}
return this;
}
aRandomNumberItem1.distinct1();
console.timeEnd('time1');//结果为1819ms,其中sort占用500ms


方案四:嵌套循环比对法--性能太差(浏览器直接卡死了)

var aRandomNumberItems = function (n){
var result = [];
for (var i = 0;i < n; i++){
var nRandom = Math.ceil(Math.random()*50);
result.push(nRandom);
}
return result;
};
var aRandomNumberItem1 = aRandomNumberItems(200);

console.time('time2');
Array.prototype.distinct2 = function () {
for (var i = 0; i < this.length-2; i++){
var nNum1 = this[i];
for (var j = i + 1;j <this.length-1; j++){
var nNum2 = this[j];
if (nNum1 === nNum2){
this.splice(j,1);
i--;
}
}
}

}
aRandomNumberItem1.distinct2();

console.timeEnd('time2');//当数组length为50000的时候,浏览器直接卡死了,当length为200时,结果为1834ms,性能太差


虽然方案一的测试效果已经很理想了,但是函数中必经还有个冗余对象obj,应该还能优化,个人水平有限,各位看官如果还有比方案一更好的方案,记得分享一下呀!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: