数组双循环比较
依次拿数组的每一项(排除最后一项:后面没有需要比较的内容了)
和当前拿出项后面的每一项进行比较
如果发现重复,把这个重复项再原有数组中删除(splice)
<script> let unique = (ary) => { for (let i = 0; i < ary.length - 1; i++) { let item = ary[i] // item:依次拿出每一项 // i:当前项的索引 //和当前项的后一项比较:起始索引应该是i+1,k<ary.length找到末尾依次比较 for (let k = i + 1; k < ary.length; k++) { // ary[k]:后面需要与当前项比较的值 if (item == ary[k]) { //相等,即重复项,在原有数组中删除 ary.splice(k, 1) //这样做会导致数组塌陷问题:删除重复项后,数组的length会发生改变,此时k累加,拿出来的结果就回跳过一位 k-- //删除后先减减,再加加,相当于没加没减 } } } return ary } let array = [1, 5, 2, 3, 4, 2, 3, 1, 3, 4] array = unique(array) console.log(array) // [1, 5, 2, 3, 4] </script>
缺点:此方法特别浪费性能
基于对象键值对方式去重
基于对象的属性名不能重复,实现高性能的数组去重
首先创建空对象
依次遍历数组中的每一项,把每一项值,当做对象的属性名和属性值存起来
存储之前判断对象中是否已经存在相同属性名(是否重复),把当前重复项在数组中移除
<script> let unique = (ary) => { let obj = {} for (let i = 0; i < ary.length; i++) { let item = ary[i] // item:依次拿出每一项 // i:当前项的索引 //存储之前需要判断,是否已存在这个属性名 if (typeof obj[item] == 'undefined') { //属性名=属性值 obj[item] = item } else { //删除方法一 ary.splice(i, 1) //删除之后索引都需要从新计算,耗性能 i-- } } return ary } let array = [1,5,2,3,4,2,3,1,3,4] array = unique(array) console.log(array) // [1, 5, 2, 3, 4] </script>
使用set
如不考虑兼容问题,可利用es6语法,set()来实现去重
<script> let unique = (ary) => { ary = Array.from(new Set(ary)) return ary } let array = [1, 5, 2, 3, 4, 2, 3, 1, 3, 4] array = unique(array) console.log(array) // [1,5,2,3,4] </script>
缺点:要考虑兼容问题
Map数组去重
<script> let unique = (ary) => { //定义常量 res,值为一个Map对象实例 const res = new Map() //返回arr数组过滤后的结果,结果为一个数组 //过滤条件是,如果res中没有某个键,就设置这个键的值为1 return ary.filter((a) => !res.has(a) && res.set(a, 1)) } let array = [1, 5, 2, 3, 4, 2, 3, 1, 3, 4] array = unique(array) console.log(array) // [1, 5, 2, 3, 4] </script>