前端学习

前端学习

@色少10年前

05/20
13:28
前端技能

数组去重的一些总结

废话不多说直接上题目!关于数组去重的例子

数组arr1和arr2,长度不固定,如何从arr1中删除和arr2中重复值的元素?

如:


var arr1=[1,3,4,6,7];

var arr2=[3,4,7];

====>

var arr3=[1,6]

console.log()

//*  ==================================================================================*//

思路1:

假如数组中的元素全是数字可以直接利用正则匹配

console.log(arr1.concat(arr2).sort().join(”).replace(/(w)1+/g,”).split(”))

思路2:

数组中包含其他类型的字符,比如:

var arr=[1,2,3,’1′,’2′,’3′,1,2]

利用hash表。把已经出现过的通过下标的形式存入一个object内。下标的引用要比用indexOf搜索数组快很多。

但是内存占用方面应该第二种方法比较多,因为多了一个hash表。这就是所谓的空间换时间。


Array.prototype.unique2 = function(){
    var n = {},r=[]; //n为hash表,r为临时数组
    for(var i = 0; i < this.length; i++) //遍历当前数组
      {
         if (!n[this[i]]) {
           //如果hash表中没有当前项
             n[this[i]] = true; //存入hash表
             r.push(this[i]); //把当前数组的当前项push到临时数组里面
          }
      }
      return r;
}

console.log([1,2,3,'1','2','3',1,2].unique2())

思路3:

先把数组排序,然后比较相邻的两个值。 排序的时候用的JS原生的sort方法,JS引擎内部应该是用的快速排序。


Array.prototype.unique3 = function(){
    this.sort();
    var re=[this[0]];
    for(var i = 1; i < this.length; i++){
       if( this[i] !== re[re.length-1]){
           re.push(this[i]);
       }
    }
    return re;
}

思路4:

利用数组的indexOf方法。此方法的目的是寻找存入参数在数组中第一次出现的位置。

很显然,js引擎在实现这个方法的时候会遍历数组直到找到目标为止。所以此函数会浪费掉很多时间。


Array.prototype.unique4 = function(){
    var n = [this[0]]; //结果数组
    for(var i = 1; i < this.length; i++) //从第二项开始遍历
    { //如果当前数组的第i项在当前数组中第一次出现的位置不是i,
      //那么表示第i项是重复的,忽略掉。否则存入结果数组
      if (this.indexOf(this[i]) == i) n.push(this[i]);
    }

    return n;
}

//*  =============================== 更新新的es5方法 ===========================*//

1、借助栈的方法

let unique = arr => {
  let res = [];
  while (arr.length > 0) {
    let item = arr.shift();
    res.indexOf(item) === -1 && res.push(item);
  }
  return res;
};
console.log(unique([1, 4, 5, 6, 6, 7, 7, 999, 999, 8, 7, 999]));

2、Array from + Set 方法
不考虑兼容性,这种去重的方法代码最少。但是无法去掉“{}”空对象


function unique (arr) { 
	return Array.from(new Set(arr)) 
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

3、Set 方法
这种去重的方法代码最少。但是set的一个最大的特点就是数据不重复


function unique(arr) {
  return [...new Set(arr)];
}

console.log(unique([1, 2, 2, 3, 4, 4]));

4、indexOf() + lastIndexOf()方法

let unique = arr => {
  let result = [];
  arr.forEach((item, index) => {
    if (arr.indexOf(item, index) === arr.lastIndexOf(item) && result.indexOf(item) === -1) {
      result.push(item);
    }
  });
  return result;
};

let arr = [1, 4, 5, 6, 6, 7, 7, 999, 999, 8, 7, 999];
console.log(unique(arr));

5、includes()方法

function unique(arr) {
  let res = [];
  arr.forEach(item => {
    if (!res.includes(item)) {
      res.push(item);
    }
  });
  return res;
}

console.log(unique([1, 2, 3, 4, 3, 3, 3, 7, 6, 6, 9, 9]));

6、hasOwnProperty

function unique(arr) {
	 var obj = {}; 
	 return arr.filter(function(item, index, arr){
	 	 return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true) 
	 }) 
} 
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; 
console.log(unique(arr)) 
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}] 
//所有 的都去重了

7、利用reduce+includes

function unique(arr){
	 return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur], []);
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; 
console.log(unique(arr)); 
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

8、利用Map数据结构去重

function arrayNonRepeatfy(arr) {
	 let map = new Map(); 
	 let array = new Array(); // 数组用于返回结果 
	 for (let i = 0; i < arr.length; i++) {
	 	 if(map .has(arr[i])) {// 如果有该key值 
	 	 	 map .set(arr[i], true); 
	 	 } 
	 	 else {
	 	 	 map .set(arr[i], false); // 如果没有该key值 
	 	 	 array .push(arr[i]);
	 	  } 
	 }
	 return array ; 
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; 
console.log(unique(arr)) 
//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]

9、利用filter


function unique(arr) { 
	return arr.filter(function(item, index, arr) {
	 	//当前元素,在原始数组中的第一个索引 === 当前索引值,否则返回当前元素 
	 	return arr.indexOf(item, 0) === index; 
	 }); 
}
 var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr)) 
 //[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]

10、简化map+filter 去重


function unique(arr) { 
	const res = new Map(); //定义常量 res,值为⼀个Map对象实例
    //返回arr数组过滤后的结果,结果为⼀个数组 过滤条件是,如果res中没有某个键如no,如没键值就直接arr,就设置这个键的值为1    
     return arr.filter((arr) => !res.has(arr.no) && res.set(arr.no, 1)) 
}
 var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr)) 
 //[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]

数组去重的一些总结