题记:我们项目中有很多的业务是需要去重的,那么下面是常用的一些去重的一些方法。
用indexOf方法去重
新建一个空数组,遍历需要去重的数组,将数组元素存入新数组中,存放前判断数组中是否已经含有当前元素,没有则存入。此方法也无法对NaN去重
indexOf() 方法:返回调用它的String对象中第一次出现的指定值的索引,从 fromIndex 处进行搜索。若未找到该值,则返回 -1
var arr2 = [1,4,6,3,4];
var xin = []
//遍历数组
for(var i=0;i<arr2.length;i++){
//通过indexOf方法返回值做判断
if (xin.indexOf(arr2[i])==-1) {
//如果没有的话就加入新的家庭,当然有的话就不用加入了
xin.push(arr2[i])
}
}
console.log("结果是",xin);
用双重for循环去重
注意:通过两层循环对数组元素进行逐一比较,然后通过splice方法来删除重复的元素。此方法对NaN是无法进行去重的,因为进行比较时NaN !== NaN。
//利用两次循环,我们找到数组当中的两个元素,进行等值判断,如果有相等的话就截取扔掉
for(let i=0;i<arr2.length;i++){
for(let j=i+1;j<arr2.length;j++){
if (arr2[j] == arr2[i]) {
arr2.splice(i,1)
}
}
}
console.log(arr2);
用for in 的方法 因为对象中不容许存在两个相同的属性名
其实现思想和Map()是差不多的,主要是利用了对象的属性名不可重复这一特性。
var obj = {}
//遍历数组加入到一个新的对象
for(let k in arr2){
obj[arr2[k]] = arr[k]
}
let xinarr = []
//遍历已经去重数组的对象然后放入数组中
for(let i in obj){
xinarr.push(i)
}
console.log(xinarr);
用new Set()方法
Set对象:是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即Set中的元素是唯一的。
Array.from() 方法:对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
console.log([...new Set(arr2)])
也可以 Array.from(new Set(arr2))
//此种方法是es6中的语法,相当于先转对象,去重完了之后,通过...把值取出来,最后再把4个值变成数组
用reduce()方法
var xin = [];
arr.reduce((preVal,curVal,index)=>{
if (xin.indexOf(curVal) == -1) {
xin.push(curVal)
}
})
console.log(xin);
利用数组的includes方法
此方法逻辑与indexOf方法去重异曲同工,只是用includes方法来判断是否包含重复元素
includes()方法:用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。
function removeDuplicate(arr) {
let newArr = []
arr.map(item => {
if (!newArr.includes(item)) {
newArr.push(item)
}
})
return newArr
} // [ 1, 2, 'abc', true, false, undefined, NaN ]
注意:为什么includes能够检测到数组中包含NaN,其涉及到includes底层的实现。如下图为includes实现的部分代码,在进行判断是否包含某元素时会调用sameValueZero方法进行比较,如果为NaN,则会使用isNaN()进行转化。
简单测试includes()对NaN的判断:
简单测试includes()对NaN的判断:
const testArr = [1, 'a', NaN]
console.log(testArr.includes(NaN)) // true
利用数组的filter()+indexOf()
filter方法会对满足条件的元素存放到一个新数组中,结合indexOf方法进行判断。
filter() 方法:会创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
function removeDuplicate(arr) {
return arr.filter((item, index) => {
return arr.indexOf(item) === index
})
}
const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined ]
注意:这里的输出结果中不包含NaN,是因为indexOf()无法对NaN进行判断,即arr.indexOf(item) === index返回结果为false。测试如下:
const testArr = [1, 'a', NaN]
console.log(testArr.indexOf(NaN)) // -1
利用Map()
Map对象是JavaScript提供的一种数据结构,结构为键值对形式,将数组元素作为map的键存入,然后结合has()和set()方法判断键是否重复。
Map 对象:用于保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值。
function removeDuplicate(arr) {
const map = new Map()
const newArr = []
arr.forEach(item => {
if (!map.has(item)) { // has()用于判断map是否包为item的属性值
map.set(item, true) // 使用set()将item设置到map中,并设置其属性值为true
newArr.push(item)
}
})
return newArr
}
-----------------或者-------------------------------------------------------
function removeDuplicate(arr) {
let map = new Map()
arr.map(item => {
if (!map.has(item)) map.set(item)
})
return [...map.keys()]
}
const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
注意:使用Map()也可对NaN去重,原因是Map进行判断时认为NaN是与NaN相等的,剩下所有其它的值是根据 === 运算符的结果判断是否相等。
总结:其实去重的语法不同,但是道理一样,都是先去重,只不过你要采取哪种语法,工作中总结是一件充实的事情,继续加油!!!