去除数组重复项
前几天在QQ群里有人提出了一个关于动态插入DOM元素的问题,并由此引出了如何删除数组中重复项的讨论,为此我写了一个小函数来实现这个需求:
var pureMultil=function(arr){
var obj={};
var a = [];
for(var i=0,l=arr.length;i < l;i++){
if(!(arr[i] in obj)){
a.push(arr[i]);
}
obj[arr[i]]="";
}
return a;
}
原理很简单:就是先把数组的项保存在一个obj字面量对象里,之后在循环中通过判断当前数组的项是否已然在obj字面对象里,并随着做不同的操作。
今天重新想到了这段代码,翻开来看看了,想到了操作符”&&”的运行机制,就利用它的特点(操作符”||”跟它正好相反):如果左边的判断为true就继续执行右边的操作。为此,修改了上面的实现方式:
var pureMultil=function (arr){
var obj={};
var a = [];
for(var i=0,l=arr.length;i < l;i++){
!(arr[i] in obj) && a.push(arr[i]) && (obj[arr[i]]="");
}
return a;
}
通过测试,在同样的条件下,速度居然呈倍数提高~《测试用例1》,示例中另外的一种实现方式由hehe123提供,不过性能上欠佳。
============================================================================
2010-6-20 updates:
为了纠正Wait在评论中所提出的对数据类型的判断来正确的处理像这样的数组:[1,"1"]。修改了下代码:
var pureMultil=function (arr){
var obj={},a = [],m,n;
for(var i=0,l=arr.length;i < l;i++){
m = arr[i];
n = typeof m;
(obj[n+m] !== m) && a.push(m) && (obj[n+m] = m);
}
return a;
}
或者使用obj的判断形式:
var pureMultil2=function (arr){
var obj={},a = [],m,n;
for(var i=0,l=arr.length;i < l;i++){
m = arr[i];
n = typeof m;
!((n+m) in obj) && a.push(m) && (obj[n+m] = "");
}
return a;
}
代码中加入了对数据类型的判断,这在循环中可想而知在性能消耗上也更多了,情况不是很佳,衡量而行,或者另寻方案。《测试页面2》
倒是如果使用普通的方式,倒显得性能最佳而且也无需字面量对象的创建和复杂的判断,虽然代码量上多了许多:《测试页面3》
var include=function (arr,item){
for(var i=0,l=arr.length;i < l;i++){
if(arr[i] === item){
return true;
}
}
return false;
}
var normalPureMultil=function (arr){
var a=[];
for(var i=0,l=arr.length;i < l;i++){
if(!include(a,arr[i])){
a.push(arr[i]);
}
}
return a;
}
总结:对于小数组形式的去除重复项,可以考虑上面代码精简的方案来处理,这样可以节省文件的大小;而如果是大数组(上千数目)来说,而且文件大小还可以凑合的话,使用普通的方式,还是比较合适的。