在工作中对于去重的例子真的太多了,面试也会经常被问到,这个真的频繁了,我整理了这些方法分享给大家,希望大家根据自己的实际场景运用。
1、ES6的Set(这个最简单)
var list = [
1,2,1,{name:1},{name:1},null, NaN,0,0,{},'','',[1],[1],null, undefined,
false,9, undefined,'true','false','true'
]
console.log(Array.from(new Set(list)))
console.log([...new Set(list)])
优点:代码少,简单
缺点:去除不了一些引用类型,比如能new
的类型:String
、Array
等
2、ES5 的Splice(这个很常用的一种)
var list = [
1,2,1,{name:1},{name:1},'Shaoyouqing','Shaoyouqing',null,null, NaN,0,0,{},'',
'',[1,2],[1,2], undefined, false,false,true,NaN,true,NaN,9, undefined,'true','false','true'
]
for(var i = 0; i < list.length; i++) {
for(var j = i + 1; j<list.length; j++) {
if(list[i] === list[j]) {
list.splice(j, 1)
j --
}
}
}
console.log(list)
优点:ES5的方法,兼容性高
缺点:去除不了一些引用类型,比如能new
的类型:String
、Array
、NaN
等
3、用新数组方式,把值存入
var list = [
1,2,1,{name:1},{name:1},'Shaoyouqing','Shaoyouqing',null,null, NaN,0,0,{},'','',
[1,2],[1,2], undefined, false,false,true,NaN,true,NaN,9, undefined,'true','false','true'
]
var arr = []
for(var i = 0; i < list.length; i++) {
if(!arr.includes(list[i])) {
// 或:if(arr.indexOf(list[i]) === -1)
arr.push(list[i])
}
}
console.log(arr)
优点:和S5 的Splice的去重差不多
缺点:去除不了一些引用类型,比如能new
的类型:String
、Array
、NaN
等
4、前后对比法
var list = [
1,2,1,{name:1},{name:1},'Shaoyouqing','Shaoyouqing',null,null, NaN,0,0,{},'','',
[1,2],[1,2], undefined, false,false,true,NaN,true,NaN,9, undefined,'true','false','true'
]
list = list.sort() //排序把一致的内容放在一起
var arr= [list[0]];
for (var i = 1; i < list.length; i++) {
if (list[i] !== list[i-1]) {
arr.push(list[i]);
}
}
console.log(arr)
优点:和S5 的Splice的去重差不多
缺点:去除不了一些引用类型,比如能new
的类型:String
、Array
、NaN
等
当然我们用递归也是一样的:
var list = [
1,2,1,{name:1},{name:1},'Shaoyouqing','Shaoyouqing',null,null, NaN,0,0,{},'','',[1,2],
[1,2], undefined, false,false,{},true,NaN,true,NaN,9, undefined,'true','false','true'
]
function loop(index) {
if(index >= 1){
if(list[index] === list[index-1]){
list.splice(index,1);
loop(index - 2); //当删除了本次的,长度减去了一个,往前移动两位
} else {
loop(index - 1); //递归loop,长度没减,往前移动一位
}
}
}
loop(list.length - 1)
console.log(list)
结果和上面的是一样的
5、getOwnProperty
利用类型+值的方式 (推荐)
var list = [
1,2,1,{name:1},{name:1},'Shaoyouqing','Shaoyouqing',null,null, NaN,0,0,{},'','',
[1,2],[1,2], undefined, false,false,true,NaN,true,NaN,9, undefined,'true','false','true'
]
var obj = {}
var arr = list.filter(item => { //用对象加值的方式
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
// 当对象含有这个值的时候,不需要返回,当没有的时候,添加到对象,并且返回
})
console.log(arr)
优点:可以很好的去除NAN
、[]
、{}
缺点:对于同类型的引用类型的精度不够,比如{},和{1}的存储内容是一致的,所以默认是同值,直接删除了,也就是这个缺点
下图为对应的obj
:
6、Map
方法去重
var list = [
1,2,1,{name:1},{name:1},'Shaoyouqing','Shaoyouqing',null,null, NaN,0,0,{},'','',[1,2],[1,2],[], undefined, false,false,{},true,NaN,true,NaN,9, undefined,'true','false','true'
]
var map = new Map()
var arr = new Array()
for (let i = 0; i < list.length; i++) {
if(map.has(list[i])) { // 如果有该key值
map.set(list[i], true)
} else {
map.set(list[i], false) // 如果没有该key值
arr.push(list[i])
}
}
console.log(arr)
优缺点和上面大部分的相似
总结下来去重的方法很多都比较类似,找不同,要么在本数组修改,或者放入新的数组,最大的优化去重就是在判断是否是相同内容上要精度更大