数组去重的意思就是去除数组中重复的元素,处理完后数组中所有的元素都是唯一的,本文介绍了在js中数组去重的5种方式,请往下看。
1. 利用Set对象
Set 对象
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
Set 中的特殊值
Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:
- +0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
- undefined 与 undefined 是恒等的,所以不重复;
- NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个,不重复。
由于Set中存储的值不能重复,所以我们可以利用Set对象来实现数组去重
//简单类型数组
const simpleArr = [1,2,2,'3','3', undefined , undefined, NaN, NaN, true, false, true, false]
//复杂类型数组
const complexArr = [2,2,'3','3', undefined , undefined, NaN, NaN,
{ id: 1, name: 'joke'},
{ id: 1, name: 'joke'},
{ id: 2, name: 'make'},
]
let result = []
// 方式一 利用Set去重
console.log(Array.from(new Set(simpleArr))) // [1, 2, '3', undefined, NaN, true, false]
console.log(Array.from(new Set(complexArr))) // [2, '3', undefined, NaN, {…}, {…}, {…}]
Array.from():对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例
但是Set中不能区分复杂类型的元素,对于object类型的变量,它只是比较变量的引用,而且NaN在Set中是相等的,所以只能应用在基本类型的数组去重情况中
2. 利用Map对象
Map 对象
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
Maps 和 Objects 的区别
- 一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。
- Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是。
- Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。
- Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
// 方式二 利用Map()
result = []
let map = new Map()
simpleArr.forEach(item=>{
if(!map.has(item)){
map.set(item,true)
result.push(item)
}
})
console.log(result) // [1, 2, '3', undefined, NaN, true, false]
Map.has() : 返回一个布尔值,用于判断 Map 中是否包含键对应的值。
Map.has()方法和Set()有点类似,也能把NaN当作相等的值,并且Map.has()方法对于object类型也只是比较其引用,所以效果和Set是相同的
3. 利用Array.indexOf()方法
indexOf() 方法可返回数组中某个指定的元素位置。
// 方式三 利用数组的indexOf方法
result = []
simpleArr.forEach(item =>{
if(result.indexOf(item)===-1){
result.push(item)
}
})
console.log(result) // [1, 2, '3', undefined, NaN, NaN, true, false]
这种方式不能对object类型和NaN进行判断,局限性较高。
4. 利用Array.includes()方法
includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。
// 方式四 利用includes方法
result = []
simpleArr.forEach(item =>{
if(result.includes(item)===false){
result.push(item)
}
})
console.log(result) // [1, 2, '3', undefined, NaN, true, false]
这个方式的思路和indexOf()大同小异,唯一不同的就是includex()能够判断NaN,底层其实是利用了isNaN()来实现的,不过也还是不能判断ojbect类型的
5. 手写一个数组去重函数
经过上面4种方式的介绍,解决基本的数组去重已经够用了,但是如果出现复杂类型的数据就不能处理了,所以需要根据实际情况手写一个数组去重函数
有这么一个数组:
const complexArr = [2,2,'3','3', undefined , undefined, NaN, NaN,
{ id: 1, name: 'joke'},
{ id: 1, name: 'joke'},
{ id: 2, name: 'make'},
]
里面存放着一下基本类型元素,还有object类型的元素,这些object类型的元素都有一个唯一标识属性id,那么我们就可以这样写:
// 方式五 手写一个去重函数
function arrayToHeavy(arr) {
let result = []
let objArr = []
let isRepeat = false
//这个循环是对基本类型的数组元素进行去重
for (let i=0; i<arr.length; i++) {
isRepeat = false
// 先判断数组元素是否为对象类型,如果符合,先存入objArr中,稍后处理
if(typeof arr[i] === 'object'){
objArr.push(arr[i])
continue
}
// 检查是否有重复的元素
for(let j=0; j<result.length; j++) {
//NaN 情况
if(isNaN(arr[i]) && arr[i]!==undefined && isNaN(result[j]) && result[j]!==undefined)
isRepeat = true
else if(result[j] === arr[i]){
isRepeat = true
break
}
}
// 检查完毕后,如果不存在重复元素则push
if(!isRepeat){
result.push(arr[i])
}
}
let objResult = []
// 这个循环是对object类型的元素进行去重
for(let i=0; i<objArr.length; i++ ) {
// 首先我们已经知道了这些元素都有一个唯一的id属性
// 可以根据比较id值进行去重
isRepeat = false
for(let j=0; j<objResult.length; j++) {
if(objResult[j].id === objArr[i].id){
isRepeat = true
break
}
}
if(!isRepeat)
objResult.push(objArr[i])
}
// 最后利用拓展运算符返回一个新数组
return [...result,...objResult]
}
console.log(arrayToHeavy(complexArr))
这个方法关键的地方就是对NaN进行识别处理,和对object类型的元素单独提取出来迭代判断
结果:
结语
在js中我们可以有很多种方式进行数组去重,当然也不仅仅只有上面的那些方式,要使用哪一种方式需要视情况而定,并且当业务需求变得复杂起来可能需要我们手写一个数组去重的方法,内部逻辑也要根据数据的格式变化
希望这篇文章能够帮助到你文章来源:https://www.toymoban.com/news/detail-732549.html
参考:js实现数组去重的方式(7种)_MomentYY的博客-CSDN博客_js去重方法文章来源地址https://www.toymoban.com/news/detail-732549.html
到了这里,关于JavaScript数组去重的方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!