javascript
数组
array
去重
distinct
unique
javascript
恰好前天面试的时候面试官问到了数组去重的问题,当时有点语塞只想到用了两个循环检测(其实模模糊糊想到了hash的方法作可是因为记得不清不敢说= =!),思路是检测是否有元素重复,而后将只出现一次的元素推入到新数组中,而后返回新数组。而后面试官又问这种方法的时间效率,因而黑线了。so这两天看了一下相关的文章,在这里也总结一下javascript数组去重的方法。css
首先,介绍一下你们都会想到的两层循环的demo,以下例:html
function distinct(arr) { var ret = [], length = arr.length; for(var i = 0;i < length; i++){ for(j = i+1; j<length;j++){ if(arr[i] === arr[j]){ j = ++i; } } ret.push(arr[i]); } return ret; } var arra = [1,2,3,4,4,1,1,2,1,1,1]; distinct(arra); //返回[3,4,2,1]
<!--more-->
如上的代码实现是轻松易得的,思路以下:java
首先外层循环比遍历整个数组git
内层循环匹配是否有值重复程序员
a.如判断有相同元素则自增i变量,跳出i的循环 b.如判断无时则将无相等值的元素推入到ret数组中
3.返回ret。github
优势:便捷易懂,大多数程序员能想到。
缺点:很明显时间消耗过高,两层循环时间消耗太多,时间的消耗为O(n^2^),在进行大量数据处理时会消耗大量资源。并且该方法没法处理字符和数组,以下例:面试
var arr = [1,23,4,5,6,7,'1',22,3,1,2]; distinct(arr); //返回[23, 4, 5, 6, 7, "1", 22, 3, 1, 2]
因此咱们能够开始考虑一些别的方法优化数组去重:chrome
这种方法就是先讲原数组使用sort方法将数组重排,以获得将相同元素为相邻位的一个新数组。该方法以下:json
function distinct(arr){ var self = arr; list = self.concat().sort(); list.sort(function(a, b){ if(a === b){ var ind = self.indexOf(a); self.splice(ind, 1); } }); return self; } var arra = [1,2,3,3,1,1,1,'1']; var arr = distinct(arra); //返回的数组为[2,3,1,'1']
一样的,在使用这种方法的重排的时候,仍然会有必定的资源消耗,在sort()函数中回调函数是使用的冒泡排序,而冒泡排序的效率并不高。可是使用这种方法的效率仍然比上一种方法的效率高,由于在此例中只出现了一次循环遍历。
优势:程序简洁,效率较高。
缺点:1.仍然没法解决数字1和字符'1'的去除。2.依赖indexOf方法,咱们知道在IE6~8中并未支持indexOf()方法。
因此咱们还要作一些兼容性的处理。以下:
var indexOf = [].indexOf ? function indexOf(arr, item){ return arr.indexOf(item); }: function indexOf(arr, item){ for(var i = 0; i < arr.length; i++){ if(arr[i] === item){ retrun i; } } return -1; } function distinct(arr){ var self = arr; list = self.concat().sort(); list.sort(function(a, b){ if(a === b){ var ind = self.indexOf(arr, a); self.splice(ind, 1); } }); return self; }
function distinct(arr) { var ret = [], json = {}, length = arr.length; for(var i = 0; i < length; i++){ var val = arr[i]; if(!json[val]){ json[val] = 1; ret.push(val); } } return ret; } var arra = [1,2,3,5,7,1,2,'1'];
以上方法更加的简洁,并且也能在原来的基础上区分字符‘1’和数字1的区别。
在此例中思路以下:
1.循环遍历每个元素
2.检测在json对象中是否含遍历到的元素的值
a: 若是是则跳过 b: 若是否存入json对象中该属性名的值设为1
3.将存入对象了元素的值推入到新数组中,返回新数组。
总结,其实数组去重无非就是判断一个元素在数组中是否有重复的值。优化也是一直改变断定元素是否重复的一些技巧,如例1中是遍历数组,例2是重排数组得到索引,例3则别出心裁将元素的值做为对象的属性。
同步于我的博客:http://penouc.com