数组去重的N种方法(10+)
2020注定是个让人无法忘怀的一年,这个年过的不知道怎么说,简单来说一个字“宅”,虽然平时也很宅吧,但是说实在的,这样被困在家里不能出门,出了门又必须戴口罩的日子,着实让我很是抑郁。。。最近不能返京工作,一个人在老家的老房子里,平时不会做饭的自己经过十几天的折磨,也快成了一个居家小能手了。当然了,敲代码这件事还是不能落下,疫情过后还得继续靠它吃饭呢。。。
好了,闲话说了一堆,切入正题吧。数组去重是我们不管是工作还是面试,出镜率最高的一道算法题。
我写的第一篇文章也是有关于数组去重的几种方法,不过这几天听了一位‘老师’的讲解,豁然开朗~~
我们要记住的不是它的每种代码怎么写,而是应该记住它解题思路,这样就变的简单了,衍生的方法也就可以说有很多种。。。
下面我就来详细的介绍一下吧:
let arr = [1,2,3,3,56,45,1,2,45,789,1,2,9];
思想一:es6,利用new Set()实现 Set对象存储任何类型的唯一值
法一:
let newArr = Array.from(new Set(arr));//利用Array.from把任意类型转换一个真正数组
console.log(newArr);
//[1, 2, 3, 56, 45, 789, 9]
法二:
let newArr1 = [...new Set(arr)];//利用es6的...扩展符
console.log(newArr);
//[1, 2, 3, 56, 45, 789, 9]
思想二:在数组中拿出当前项和后面的内容进行比较
法一:for循环,如果后面项里面存在当前项,那就删除当前项
for(let i=0;i<arr.length-1;i++){
let cur=arr[i];
let next = arr.slice(i+1);
if(next.indexOf(cur)>-1){//
arr.splice(i,1);
i--;
}
}
console.log(arr);
//[1, 2, 3, 56, 45, 789, 9]
法二:for循环,创建新数组,如果后面项里面不存在当前项,放入新数组
let newArg = [];
for(let i=0;i<arr.length;i++){
let cur=arr[i];
let next = arr.slice(i+1);
if(next.indexOf(cur)==-1){//如果不包括
newArg.push(cur);
}
}
console.log(newArg);
//[3, 56, 45, 789, 1, 2, 9]
法三:for循环,如果后面项里面存在当前项,把数组最后一项替换当前项,删除最后一项
for(let i = 0;i<arr.length-1;i++){
let cur = arr[i];
let next = arr.slice(i+1);
if(next.includes(cur)){//如果存在,把数组最后一项替换当前项,删除最后一项
arr[i]=arr[arr.length-1];
arr.length--;
i--;
}
}
console.log(arr);
//[9, 789, 2, 3, 56, 45, 1]
法四:for循环,如果后面项里面存在当前项,把当前项变成null,然后利用filter过滤
for(let i = 0;i<arr.length-1;i++){
let cur =arr[i];
let next = arr.slice(i+1);
if(next.includes(cur)){
arr[i]=null;
}
}
arr = arr.filter((item)=>{
return item!==null;
})
console.log(arr);
//[3, 56, 45, 789, 1, 2, 9]
法五:for循环,和法四类似 只是复制了一份新数组再过滤
let newArg = [...arr];
for(let i = 0;i<arr.length-1;i++){
let cur =arr[i];
let next = arr.slice(i+1);
if(next.includes(cur)){
newArg[i] =null;
}
}
newArg = newArg.filter((item)=> item!==null);
console.log(newArg);
// [3, 56, 45, 789, 1, 2, 9]
法六:双for循环,当前项和后面的每一项做比较,如果相同,删除相同项
for(let i=0;i<arr.length;i++){
for(let j=i+1;j<arr.length;j++){
if(arr[i]==arr[j]){
arr.splice(j,1);
j--;
}
}
}
console.log(arr);
// [1, 2, 3, 56, 45, 789, 9]
思想三 :创建新的数组 和原来数组每一项作对比
法一:for循环 如果新数组里不存在 就把当前项放入新数组中
let newArr = [];
for(let i=0;i<arr.length;i++){
if(!newArr.includes(arr[i])){
newArr.push(arr[i]);
}
}
console.log(newArr);
//[1, 2, 3, 56, 45, 789, 9]
法二:forEach 如果新数组里不存在 就把当前项放入新数组中
let newArr = [];
arr.forEach((item)=> newArr.includes(item)?'':newArr.push(item));
console.log(newArr);
//[1, 2, 3, 56, 45, 789, 9]
法三:过滤 filter 如果新数组里不存在 就把当前项放入新数组中
let newArr = [];
newArr = arr.filter((item)=> newArr.includes(item)?'':newArr.push(item));
console.log(newArr);
//[1, 2, 3, 56, 45, 789, 9]
法四:利用reduce push进新数组
arr = arr.reduce((prev,cur)=>{
if(!prev.includes(cur)){
prev.push(cur);
}
return prev;
},[]);
console.log(arr);
//[1, 2, 3, 56, 45, 789, 9]
法五:利用reduce 数组concat拼接新数组
arr = arr.reduce((prev,cur)=>{
if(!prev.includes(cur)){
return prev.concat(cur);
}else{
return prev;
}
},[])
console.log(arr);
//[1, 2, 3, 56, 45, 789, 9]
法六: 创建对象 拿数组中的每项向新容器中存储,如果已经存储过了,把当前项干掉,用最后一项替换当前项
let obj = {};
for(let i=0;i<arr.length;i++){
let key = arr[i];
if(obj[key]){ typeof obj[key]!=='undefined'
arr[i] = arr[arr.length-1];
arr.length--;
i--;
continue;
}
obj[key]=key;
}
obj=null;
console.log(arr);
//[1, 2, 3, 9, 56, 45, 789]
法七: 创建数组 拿数组中的每项向新容器中存储,如果已经存储过了,把当前项干掉,用最后一项替换当前项
let newArr = [];
for(let i=0;i<arr.length;i++){
let item = arr[i];
if(newArr.includes(item)){
arr[i]=arr[arr.length-1];
arr.length--;
i--;
continue;
}
newArr.push(item);
}
console.log(arr);
console.log(newArr);
//[1, 2, 3, 9, 56, 45, 789]
//[1, 2, 3, 9, 56, 45, 789]
思想四:先排序 然后相邻的元素进行对比
法一:for循环
arr.sort((a,b)=>a-b);
let newArr = [];
for(let i=0;i<arr.length;i++){
let cur = arr[i];
let next = arr[i+1];
if(cur!==next){
newArr.push(cur);
}
}
console.log(newArr);
//[1, 2, 3, 9, 45, 56, 789]
法二:正则
arr.sort((a,b)=>a-b);
arr=arr.join('@')+'@';
let reg=/(\d+@)\1*/g,// \1* 分组引用,出现0到多次出现一样的
newArr=[];
arr.replace(reg,(val,group1)=>{
newArr.push(parseFloat(group1));
});
console.log(newArr);
//[1, 2, 3, 9, 45, 56, 789]
恩,差不多四种思想,基本就这样吧,里面indexOf和includes可以互换也可以衍生出更多的方法,这里就不继续写了,我数了一下有十七八种了,不继续写啦~~~