第一种是比较常规的方法
思路:
1.构建一个新的数组存放结果
2.for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比
3.若结果数组中没有该元素,则存到结果数组中
代码如下 | 复制代码 |
Array.prototype.unique1 = function(){ var res = [this[0]]; for(var i = 1; i < this.length; i++){ var repeat = false; for(var j = 0; j < res.length; j++){ if(this[i] == res[j]){ repeat = true; break; } } if(!repeat){ res.push(this[i]); } } return res; } var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0] alert(arr.unique1()); |
第二种方法比上面的方法效率要高
思路:
1.先将原数组进行排序
2.检查原数组中的第i个元素 与 结果数组中的最后一个元素是否相同,因为已经排序,所以重复元素会在相邻位置
3.如果不相同,则将该元素存入结果数组中
代码如下 | 复制代码 |
Array.prototype.unique2 = function(){ this.sort(); //先排序 var res = [this[0]]; for(var i = 1; i < this.length; i++){ if(this[i] !== res[res.length - 1]){ res.push(this[i]); } } return res; } var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0] alert(arr.unique2()); |
第二种方法也会有一定的局限性,因为在去重前进行了排序,所以最后返回的去重结果也是排序后的。如果要求不改变数组的顺序去重,那这种方法便不可取了。
第三种方法(推荐使用)
思路:
1.创建一个新的数组存放结果
2.创建一个空对象
3.for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复,则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为1,存入到第2步建立的对象中。
说明:至于如何对比,就是每次从原数组中取出一个元素,然后到对象中去访问这个属性,如果能访问到值,则说明重复。
代码如下 | 复制代码 |
Array.prototype.unique3 = function(){ var res = []; var json = {}; for(var i = 0; i < this.length; i++){ if(!json[this[i]]){ res.push(this[i]); json[this[i]] = 1; } } return res; } var arr = [112,112,34,'你好',112,112,34,'你好','str','str1']; |
上面整理的JS数组去重的方法。之前比较公认的一种快速方式是引用类似hash表的思想。代码如下:
Js代码
代码如下 | 复制代码 |
var ddd = [1,2,4,5,2, 222,1,5,6]; var uq = {}; var rq = []; for(var i=0; i<9; i++){ if(!uq[ddd[i]]){ uq[ddd[i]] = true; rq.push(ddd[i]); } } return rq; |
但是这个方法有个很大的疏漏,就是没有考虑到 '222' 和 222 这种元素会被当作相同元素被剔除的情况。于是我做了如下的修改。
Js代码
代码如下 | 复制代码 |
var ddd = [1,2,4,5,2, '222', 222,1,5,6]; var uq = {}; var rq = []; var prefix = ''; for(var i=0; i<8; i++){ if(typeof ddd[i] == 'string' ) { prefix = '_str'; } else { prefix = ''; } if(!uq[ddd[i]+prefix]){ uq[ddd[i]+prefix] = true; rq.push(ddd[i]); } } return rq; |
没做什么高深的修改,就是加了个前缀,区分下。这样,结果就是 [1,2,4,5,'222', 222,6]
去重并计数问题
代码如下 | 复制代码 |
function test(s) { var hash={}; s.replace(/[a-z]/ig,function ($1) { alert($1); if ($1 in hash) hash[$1]++; else hash[$1]=1; }); return hash; }
|
看来我把问题说简单了,呵呵,如果字符串中出现了同样的数字呢?如果我要比对的是汉字组成的字符串数组呢?如:{"番茄炒蛋","泡椒牛柳","香干肉丝","番茄炒蛋","香干肉丝","蜜汁鸡腿"....}
代码如下 | 复制代码 |
function test(s) { var hash={}; s.replace(/[a-z]/ig,function ($1) { alert($1); if ($1 in hash) hash[$1]++; else hash[$1]=1; }); return hash; } |
其实我的意思就是:一个字符串的数组,在一张页面的table中,比如“套餐”这样的字段。有不同的人点了不同的饭,也有不同的人点了相同的饭,最后做一个统计:什么饭有几份。如:如:{"番茄炒蛋","泡椒牛柳","香干肉丝","番茄炒蛋","香干肉丝","蜜汁鸡腿"},需要得到结果:番茄炒蛋2份,泡椒牛柳1份,香干肉丝2份,蜜汁鸡腿1份。这样应该说清楚了吧?
下面是补充
代码如下 | 复制代码 |
<html> <head> <script type="text/javascript"> var a=['a','b','c']; var b=['a','b','d','f']; var arr1 = intersection(a,b); alert("a,b的合集-不重复:"+arr1); var arr2 = chaji(a,b); alert("a与b不重复的部分:"+arr2); var arr3 = inANotInB(a,b); alert("b与a不重复的部分:"+arr3); //a,b合集 function intersection(a,b){ var obj = new Object(); for(var i =0,len = a.length;i<len;i++){ obj[a[i]] = a[i]; } for(var i =0,len = b.length;i<len;i++){ obj[b[i]] = b[i]; } var arr = new Array(); var i = 0; for(var per in obj){ arr[i++] = obj[per]; } return arr; } //a与b不重复的部分 function chaji(a,b){ var obj = new Object(); for(var i =0,len = a.length;i<len;i++){ obj[a[i]] = 1; } for(var i =0,len = b.length;i<len;i++){ obj[b[i]] = obj[b[i]]?2:1; } var arr = new Array(); var i = 0; for(var per in obj){ if(obj[per] == 1){ arr[i++] = per; } } return arr; } //b与a不重复的部分 function inANotInB(a,b){ var obj = new Object(); for(var i =0,len = a.length;i<len;i++){ obj[a[i]] = 1; } for(var i =0,len = b.length;i<len;i++){ if(obj.hasOwnProperty(b[i])){ obj[b[i]] = undefined; } } var arr = new Array(); var i = 0; for(var per in obj){ if(obj[per]){ arr[i++] = per; } } return arr; } </script> </head> </html> |