js 数组去重
数组去重的方法以及思路
ES6 Set去重
该方法会略过引用类型,因为 set 方法的机制问题会产生一个这样的类数组
let arr = [1,undefined,1,undefined,'true',true,true,15,false,false,[1],[2],{},[1],{},NaN,null,NaN,null,0,0,'a','a'];
// ES6 Set去重
let setArr = Array.from(new Set(arr));
console.log(setArr);
set 通过集合去重的方式, 保证了伪数组中, 基本数据类型的唯一性, 但会忽略引用类型
再通过 from 方法, 得到的结果如下所示:
比较去重
该方法是最简单的去重法, 通过遍历比较将每个值存入新数组, 得到的结果比较拉胯
let arr = [1,undefined,1,undefined,'true',true,true,15,false,false,[1],[2],{},[1],{},NaN,null,NaN,null,0,0,'a','a'];
//indexOf方法 (无法判断NaN)
function indexRepeat(arr){
let indexArr = [];
for(let i=0; i < arr.length; i++){
if(indexArr.indexOf(arr[i]) === -1 ){
indexArr.push(arr[i]);
}
}
return indexArr
}
因为 NaN 和任何值比较都为 false ,引用类型比较的又是指针
原型深度去重
该方法通过 原型 + 值 的写法, 比较的不仅仅是数据类型, 还有值, 再通过对象键名不能重复的特性, 完成了深度去重
let arr = [1,undefined,1,undefined,'true',true,true,15,false,false,[1],[2],{},[1],{},NaN,null,NaN,null,0,0,'a','a'];
// 原型深度去重
function repeat(){
let obj = {};
return arr.filter(val => {
return obj.hasOwnProperty(typeof val + val ) ? false : (obj[typeof val + val ] = true)
})
}
console.log(repeat(arr));
既然比较原型和只比较值都不可取,那么我们这个方法吸取了上面的经验,
将类型和值放在一起再进行比较,得到了以下结果:
最终使用ES6新增的filter方法,完美完成了数组去重
总结
let arr = [1,undefined,1,undefined,'true',true,true,15,false,false,[1],[2],{},[1],{},NaN,null,NaN,null,0,0,'a','a'];
// ES6 Set去重
let setArr = Array.from(new Set(arr));
console.log(setArr);
//indexOf方法 (无法判断NaN)
function indexRepeat(arr){
let indexArr = [];
for(let i=0; i < arr.length; i++){
if(indexArr.indexOf(arr[i]) === -1 ){
indexArr.push(arr[i]);
}
}
return indexArr
}
console.log(indexRepeat(arr));
// 原型深度去重
function repeat(){
let obj = {};
return arr.filter(val => {
return obj.hasOwnProperty(typeof val + val ) ? false : (obj[typeof val + val ] = true)
})
}
console.log(repeat(arr));