最近,碰到了数组去重,我来办它啦!
方法一:最容易想到的思路
1、创建一个新数组,并循环遍历原数组,将遍历的元素依次存放到新数组中;
2、循环遍历时,在新数组中对比是否有重复元素,如果有则终止遍历,否则,存放至新数组。
【注】为了兼容更多浏览器,我使用的是for循环,而没有用forEach简化。
let arr = [1,2,3,4,2,2,1,3] let newArr = [] for(let i=0; i<arr.length;i++) { let item = arr[i]; //存放遍历到的元素 if(newArr.includes(item)) { continue; } newArr.push(item); }
方法二:一个麻烦的思路o(╥﹏╥)o,主要是为了引出数组塌陷的问题。
1、依次拿出数组的每一项A,用这一项A和它后面的每一项依次比较;
2、如果遇到和当前A相同的元素,则在原数组中把这一项移除掉。
let arr = [1,2,2,4,3,3,1] for(var i=0;i<arr.length;i++) { var item = arr[i]; for(var j=i+1;j<arr.length;j++) //当前项item后面所有的内容 { var compare = arr[j]; if(compare == item) { arr.splice(j,1); j--; //数组塌陷的解决方法 } } }
在哪引起了数组塌陷?为什么呢?该怎么解决呢?
在内层循环的时候引起了数组塌陷:索引 j 后面的每一项索引都提前了一位!但是下次要比较的应该还是 j 这个索引的内容!所以我们在j++之后又将j- -,这样 j 索引就不会出错了。
方法三:对象法
1、循环数组中的每一项,把每一项放至对象obj中进行存储:item 属性名/值:item变量存的值,obj [item]=item;
2、如果遇到obj[val]===val,那么该项一定存在,则删除;否则,追加到对象中;
3、永远记得处理数组塌陷问题。
可以看一下图解:
let arr = [1,2,2,4,3,3,1]; let obj={}; for(let i=0; i<arr.length;i++) { let item = arr[i]; if(obj[item] !== undefined) //obj中是否存在这一项 { arr.splice(i,1); i--; //注意数组塌陷的问题 continue; } obj[item]=item }
上述方法虽然都实现了数组的去重,但性能如何呢??是的,并不好。因为都使用到了splice方法,此方法的当前一项被删除,那么后面每一项的索引都要向前提一位,如果后面内容过多,一定影响性能。所以,我们引入了方法四...
方法四:对象法的优化
用最后一项换取当前重复项,同时删除最后一项。【代替splice方法】
同时进行了函数封装,方便使用。
//unique实现数组去重,返回去重后的数组 function unique(arr) { let obj={}; for(let i=0;i<arr.length;i++) { let item = arr[i]; if(obj[item] !== undefined) { arr[i] = arr[arr.length-1]; arr.length--; //删除数组最后一项 i--; continue; } obj[item] = item; } return arr; } console.log(unique([1,2,3,2,1,1,2]));
方法五:正则表达式
1、将数组转化为以@符间隔的字符串;
2、使用正则表达式:如果数字从1开始并且有一个@符,且出现了多次;
3、将不符合正则表达式的元素追加至新数组中。
let arr = [1,2,3,2,2,3]; arr.sort((a,b) => a - b); //按升序排数组 let str = arr.join('@')+'@'; let reg = /(d+@)1*/g; let newArr = []; str.replace(reg,(n,m)=>{ m=Number(m.slice(0,m.length-1)); newArr.push(m); }); console.log(newArr);
方法六:ES6 SET
let arr = [1,2,3,2,2,3]; arr = [...new Set(arr)]; console.log(arr);
以上就是我整理的一些数组去重的方法,希望对你有帮助呀!^_^