数组双循环比较
依次拿数组的每一项(排除最后一项:后面没有需要比较的内容了)
和当前拿出项后面的每一项进行比较
如果发现重复,把这个重复项再原有数组中删除(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>