需要去重的数组可能是普通数组或者是对象数组,下面先写普通数组
// 普通数组例子
let arr1 = ['zs', 'zs', 'ls', 'ls', 'ww', 0, 0, 1, 1, true, true, NaN, NaN, undefined, undefined, null, null]
主要有两种思路
利用双重循环
利用语法特性
利用双重循环
双重for循环原数组,直接在原数组上去除重复值
function deDuplication(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1)
j--
}
}
}
return arr
}
console.log(deDuplication(arr1))
// [ 'zs', 'ls', 'ww', '', 0, 1, true, NaN, NaN, undefined, null ]
- 由于 '===' 判断时,
NaN
是不等于自身的,所以如果数组中可能包含NaN
,可以用isNaN()
方法判断再去重
使用indexOf
/ includes
通过额外的数组储存不重复的值,一遍遍历原数组,另一遍使用indexOf/includes
遍历结果数组
function deDuplication(arr) {
let result = []
arr.forEach(cur => {
// indexOf写法: result.indexOf(cur) === -1 ? result.push(cur) : ''
result.includes(cur) ? '' : result.push(cur)
})
return result
}
console.log(deDuplication(arr1))
// [ 'zs', 'ls', 'ww', 0, 1, true, NaN, undefined, null ]
- 需要注意的是
indexOf
内部使用的是===
还是会有NaN !== NaN
的问题 - 当数组有空值时,
includes
会将空值当做undefined
,indexOf
则不会
let arr3 = [ , ]
console.log(arr3.includes(undefined)) // true
console.log(arr3.indexOf(undefined)) // -1
利用语法特性
Set 数据结构
console.log([...new Set(arr1)])
// [ 'zs', 'ls', 'ww', 0, 1, true, NaN, undefined, null ]
- Set类似数组,成员值都是唯一的,因此可以用创建Set对象再转成数组的方式去重
Map 数据结构
function deDuplication(arr) {
let checkList = new Map() // 用于查重
let result = [] // 去重后的数组
arr.forEach(cur => {
if (!checkList.has(cur)) {
checkList.set(cur)
result.push(cur)
}
})
return result
}
console.log(deDuplication(arr1))
// [ 'zs', 'ls', 'ww', 0, 1, true, NaN, undefined, null ]
- 该方法类似于利用对象键名必须唯一的方式去重,但“ 一个
Object
的键必须是一个 String或Symbol”,而Map则可以用任意类型的值(包括对象)作为键,因此Map适用范围更广
普通数组的查重主要是上面两种思路,很多方法都是大同小异,一般直接上Set就好啦