zl程序教程

您现在的位置是:首页 >  前端

当前栏目

javascript删除数组中重复项(uniq)

JavaScript数组 删除 重复 uniq
2023-06-13 09:14:15 时间
可以直接使用的代码:脚本之家修正版


下面是进阶教程与说明,喜欢跟深入的朋友可以参考下。
首先让我们看下YUI是如何处理的:
复制代码代码如下:

vartoObject=function(a){
varo={};
for(vari=0;i<a.length;i=i+1){
o[a[i]]=true;
}
returno;
};

varkeys=function(o){
vara=[],i;
for(iino){
if(lang.hasOwnProperty(o,i)){//YUI的方法
a.push(i);
}
}
returna;
};

varuniq=function(a){
returnkeys(toObject(a));
};

详细分析,见同事长天的分享《巧妙去除数组中的重复项》。

自己使用的方式与YUI的方式十分相似,不过仅使用了一次循环便完成了删除数组中重复项,如下:
复制代码代码如下:

varuniq=function(arr){
vara=[],
o={},
i,
v,
len=arr.length;

if(len<2){
returnarr;
}

for(i=0;i<len;i++){
v=arr[i];
if(o[v]!==1){
a.push(v);
o[v]=1;
}
}

returna;
}

经过了简单的测试:自己使用的方式性能远远高于YUI的方式。

抛砖引玉,欢迎大家提供更好的处理方法。

2009年12月28日更新:

以上两种函数方法暂时都不能处理复杂的含有混合类型的数组(感谢小猫提出的疑问),如:[0,"0",1,"1",0]、["null",null]。

对于能够约定类型为数字(注:要求非0开头的数字,小数除外)或字符串的数组,我们可以用改进后的函数方法(感谢closurecache提供的思路):
复制代码代码如下:
varuniq=function(arr){
vara=[],
o={},
i,
v,
cv,//correctedvalue
len=arr.length;

if(len<2){
returnarr;
}

for(i=0;i<len;i++){
v=arr[i];

/*closurecache提供的函数中使用的是cv=v+0;,
*这样就无法辨别类似[1,10,"1","10"]的数组,
*因为运算后=>1,10,10,100,很明显,出现了重复的标示符。
*加前面就难道没问题吗?
*有的:数组中不能出现类似01、001,以0开头的数字,
*但适用性比原先更广。
*/
cv=0+v;

if(!o[cv]){
a.push(v);
o[cv]=true;
}
}

returna;
}

如果大家想在此解题思路的基础上,更完美一点,推荐Dexter.Yy的方法,进行类型判断,给予唯一标示符,详见评论20楼。

没有最好,只有最合适的方式,其实使用Array.indexOf()的思路也是不错的选择,对于已经支持的浏览器直接用原生的Array.indexOf()方法,对于未支持的,我们增加Array.indexOf()方法,如下:
复制代码代码如下:
if(!Array.prototype.indexOf){
Array.prototype.indexOf=function(obj,fromIndex){
if(fromIndex==null){
fromIndex=0;
}elseif(fromIndex<0){
fromIndex=Math.max(0,this.length+fromIndex);
}

for(vari=fromIndex;i<this.length;i++){
if(this[i]===obj)
returni;
}
return-1;
};
}

接下来,实现的过程就非常简单了。

对于使用Array.indexOf()方法实现方案的优化提示:找到相同值时,从数组中移除,以减少下次遍历的量。