数组去重是笔试及面试时的重要考题,现对已有方法进行如下总结:
(1)思路:新建一个空的数组newArr,将需要去重的数组中的第一个元素传入,依次与原数组中剩余的元素进行比较,不重复则把元素传入到新数组newArr中。
这种方法实现思路简单,由于使用‘===’,可以实现对类似2和‘2’这种数字与字符串的比较。但是该算法创建了新的数组,并且使用双层循环,对时间和空间均存在一定的浪费。
1 Array.prototype.unique1 = function(){ 2 var newArr = [this[0]]; 3 //flag用来比较数组是否重复,不重复为true,重复为false 4 var flag = true; 5 for(var i = 1;i < this.length;i++){ 6 for(var j = 0; j < newArr.length; j++){ 7 if(newArr[j] === this[i]){ 8 flag = false; 9 break; 10 }else{ 11 flag = true; 12 } 13 } 14 if(flag){ 15 newArr.push(this[i]); 16 } 17 } 18 } 19 20 var arr=[1,2,2,'2',3,4,4,'a','a','b']; 21 console.log(arr.unique1());
(2)思路:将原数组进行排序,排序之后的数组相同的元素是相邻的。新建一个数组newArr并存入原数组经过排序之后的第一个元素,遍历排序后的数组,将数组中的各个元素与newArr中的最后一个元素对比,如果二者不相等则存入newArr中。
这种方法实现思路简单相对第一种方法减少了一层循环,但由于原数据是经过排序的,如果要求不改变原数组元素的位置,该方法就不再适用。
Array.prototype.unique2 = function(){ this.sort(); var newArr = [this[0]]; for(var i = 1; i < this.length; i++){ if(this[i] !== newArr[newArr.length - 1]){ newArr.push(this[i]); } } return newArr; }
(3)思路:利用对象的相关特性,对象的组成方式为obj{'key','value'},对象中key值不可以重复,但是value值不要求。新建一个空的数组newArr,一个空的对象,遍历需要去重的数组,利用对象key不能重复的特性实现数组去重。
该方法独辟蹊径,推荐使用,但存在的问题是最终得到的结果均为字符串类型。
Array.prototype.unique3 = function(){ var obj = {}; var newArr = []; for(var i = 0,j = this.length;i < j; i++){ //将原数组做为obj的key值,value值均为空。由于key值具有唯一性,因此key值重复时,key保持不变,value进行覆盖 obj[this[i]] = " "; } for(var items in obj){ newArr.push(items); }
return newArr; }
利用以下代码,可以达到数组去重并且保证了数据类型不变,字符串类型的“数字”和真正的数字区分
Array.prototype.unique3 = function(){ var obj = {},newArr = []; for(var i = this.length - 1;i >= 0; i--){ if(obj[this[i]] == undefined || obj[this[i]] !== this[i]){ obj[this[i]] = this[i]; newArr.push(this[i]); } } return newArr.reverse(); }
(4) 思路:利用正则表达式
Array.prototype.unique4 = function(){ return this.join(,).match(/([^,]+)(?!.*\1)/ig); }
(5)思路:与1类似,从原数组最后一个元素开始比较,因此最终数组需要反转。统一来说,采用多重循环程序效率都不高;因此推荐使用对象前去重或利用正则表达式。
Array.prototype.unique5 = function(){ var newArr = []; var flag = true; var i = this.length; var j = 0; newArr[0] = this[i-1]; while(--i >= 0){ j = newArr.length; while(--j >= 0){ flag = newArr[j] != this[i]; if(!flag) break; } flag && newArr.push(this[i]); } return newArr.reverse(); }