数组去重方法合(本章总结七大类)
- 首先,我们制造一些数组来测试我们的去重方法
// 纯数字数组
var arr_1=[1,6,3,3,1,2,2,2,6];
// 字符串数组
var arr_2=['123','asc','qw2','qw2','123','123','qw2','ghh'];
// 数字+字符串数组
var arr_3=[1,'a',2,2,'a','a','1'];
// DOM对象是类数组--页面至少写一个div
var byTag_div=document.getElementsByTagName('div');
var seAll_div=document.querySelectorAll('div');
// 复合数组--各种数据类型
var arr_4=[[1,4],{'a':0},[1,4],byTag_div,seAll_div,{'a':0},'1',undefined,undefined,NaN,'a',null,'a',1,null,NaN,1];
!原理:js语法(分支、循环、函数及封装)+玩转各类API。
提示:看不懂的API(以下称方法)查标准
1.基础方法(splice()、sort()、递归)
!look,用脚都能想到的方法
- 1-1.双重for循环+splice()
function unique_1(arr){
// 不修改原数组--如想修改原数组,这个步骤不需要,直接对arr进行操作
var c_arr=JSON.parse(JSON.stringify(arr));
for(var i=0;i<c_arr.length;i++){
for(var j=i+1;j<c_arr.length;j++){
// 判断前后项若相等,则删除后一项,通过循环再次将前一项和后面的项进行比较。
if(c_arr[i]===c_arr[j]){
c_arr.splice(j,1);
j--;
}
}
}
// 返回去重后的数组
return c_arr;
}
!测试:
console.log(unique_1(arr_1));
console.log(unique_1(arr_2));
console.log(unique_1(arr_3));
console.log(unique_1(arr_4));
!look 上图输出结果:
1.无法对对象(包括数组去重);
2.对数据类型undefined和NaN去重错误;
3.两个伪数组的内部也发生了变化。
- 1-2 数组排序
function unique_2(arr){
arr.sort(function(a,b){return a-b;});
// 新数组先存储第一项
var c_arr=[arr[0]];
// 遍历数组
for(var i=1;i<arr.length;i++){
// 判断前后项--若不等,则添加
if(arr[i]!==arr[i-1]){
c_arr.push(arr[i]);
}
}
return c_arr;
}
结果自行测试,因为用到排序,仅用于能够排序的数组去重。例:字母字符串数组无法去重。
!只要去重原理依靠排序,就要注意存在字符串项的数组。
- 1-3 排序+递归
function unique_3(arr){
var len=arr.length;
arr.sort(function(a,b){return a-b;});
function loop(index){
if(index>=1){
if(arr[index]===arr[index-1]){
arr.splice(index,1);
}
loop(index-1);
}
};
loop(len-1);
};
!会改变原数组,测试直接打印原数组。
2.利用indexOf()、lastIndexOf及includes–用于查找
function unique_4(arr){
var c_arr=[];
// forEach代替循环
arr.forEach(function(item){
// 查找每一项;如无,则添加
// if(c_arr.indexOf(item)===-1){
// c_arr.push(item);
// }
// if(c_arr.lastIndexOf(item)===-1){
// c_arr.push(item);
// }
if(!c_arr.includes(item)){
c_arr.push(item);
}
});
return c_arr;
}
3.filter()方法
function unique_5(arr){
return arr.filter(function(item,index){
return arr.indexOf(item)===index;
});
}
4.map()方法
function unique_6(arr){
var map=new Map();
var c_arr=[];
arr.forEach(function(item,index){
if(map.has(item)){
map.set(item,true);
}else{
map.set(item,false);
c_arr.push(item);
}
});
return c_arr;
}
5.obj属性+…
例:obj的hasOwnProperty()方法+filter()方法
function unique_7(arr){
// 创建对象
var obj={};
// 返回筛选后的数组
return arr.filter(function(item){
// 筛选条件--通过对象的hasOwnProperty方法精确判断数据类型是引用类型,则判断内部的值。
return obj.hasOwnProperty(typeof item+item)?false:(o[typeof item+item]=true);
});
}
!这种方法可以精确判断类型和引用类型的内置属性
6.reduce()和includes()
function unique_8(arr){
return arr.reduce((prev,cur)=>prev.includes(cur)?prev:[...prev,cur],[]);
}
7.ES6新增set()方法
function unique_9(arr){
return Array.from(new Set(arr));
}