彻底搞定各种数组去重需求
前言
数组去重是面试时候常考的,我们日常工作中,也经常会遇到, 接下来就归纳总结几种数组去重的方案, 在我们开发和面试的时候可以得心应手,
分类
在实现数组去重之前我们我们简单进行一下分类, 数组去重,我们一般 分为单个数组去重 和多个数组交叉去重, 接下来我们就从单个数组开始
一、简单的数组去重
简单数组去重经常是普通数组进行去重, 我们常用的是利用new Set去重、利用indexOf、数组方法 some、 filter 、reduce 等
1、new Set
这种方案很简单, 就是将数组转化成Set结构, 利用Set结构的唯一性去重, 然后再转化为数组
const arr = [1,2,3,1,2,2]
new Set(arr)
set 结构转换成 数组 有两种方式 [...new Set(arr)]和 Array.from(new Set(arr))
// [1, 2, 3]
2、使用 遍历(map、for循环、forEach) + indexOf
const arr = [1,2,3,1,2,2]
let arr2 = []
for(let i=0;i<arr.length;i++){
if(arr2.indexOf(arr[i]) === -1){
arr2.push(arr[i])
}
}
//=> arr2 [1, 2, 3]
3、使用 reduce、reduceRight 去重
上面的方法其实是经典的面相过程的写法,我们为了达到结果,引入了新的变量arr2 , 如果是面向对象的写法,又不引入新的变量,我们经常使用 reduce、reduceRight
const arr = [1,2,3,1,2,2]
arr.reduce((result, cur, index, array)=>{
if(result.indexOf(cur) === -1){
result.push(cur)
}
return result
},[])
4、利用对象 key的唯一性 去重
再考虑去重的时候,经常也会使用 对象的key唯一性这个特点进行去重, 先写一个面向过程的写法, 引入一个变量 obj
const obj = {}
const result = []
const arr = [1,2,3,1,2,2]
arr.map(el=>{
if(!obj[el]){
result.push(el)
obj[el] = el
}
})
console.log(result) //=> [1, 2, 3]
同理 也可也通过面向对象方式 用reduce 解决
const arr = [1,2,3,1,2,2]
const obj = {}
arr.reduce((result, cur, index,array)=>{
if(!obj[cur]){
result.push(cur)
obj[cur] = cur
}
return result
},[])
//=> [1, 2, 3]
5、filter 去重
const arr = [1,2,3,1,2,2]
arr.filter((el,index)=> !arr.slice(0,index).some(t=> t === el))
或
arr.filter((el,index)=> arr.indexOf(el)
//=> [1, 2, 3]
二、复杂的JSON数组去重
复杂数组去重 , 一般是 JSON数组去重, 根据某个对象的key相同去重, 基本上大体也是利用上面简单数组去重的原理。
下面以这个举例, 我们按照相同id去重
const arr = [{id:1, name: 'liming'},{id:2, name:'xiaohong'}, {id:1, name: 'liming2'}]
1、使用 遍历(map、for循环、forEach) + indexOf
let arr = [{id:1, name: 'liming'},{id:2, name:'xiaohong'}, {id:1, name: 'liming2'}]
let arr2 = []
let result = []
for(let i=0;i<arr.length;i++){
if(arr2.indexOf(arr[i].id) === -1){
result.push(arr[i])
arr2.push(arr[i].id)
}
}
// result => [{id: 1, name: 'liming'},{id: 2, name:'xiaohong}]
// arr2 => [1,2]
这里也是通过 arr2 的引入,来存取id每个对象中id的值。 判断是否已存在这个id ,在判断是否讲 item 放入 result中
2、使用 reduce、reduceRight 去重
let arr = [{id:1, name: 'liming'},{id:2, name:'xiaohong'}, {id:1, name: 'liming2'}]
arr.reduce((result, cur, index, array)=>{
let r = array.slice(0,index).filter(el=> el.id === cur.id)
if(!r.length){
result.push(cur)
}
return result
},[])
// result => [{id: 1, name: 'liming'},{id: 2, name:'xiaohong}]
// arr2 => [1,2]
3、利用对象 key的唯一性 去重
let arr = [{id:1, name: 'liming'},{id:2, name:'xiaohong'}, {id:1, name: 'liming2'}]
let obj = {}
let result = []
arr.map((cur,index)=>{
f(!obj[cur.id]){
result.push(cur)
obj[cur.id] = true
}
})
// result => [{id: 1, name: 'liming'},{id: 2, name:'xiaohong}]
4、利用 map + filter
let arr = [{id:1, name: 'liming'},{id:2, name:'xiaohong'}, {id:1, name: 'liming2'}]
let result = []
arr.map((cur, index)=>{
let r = arr.slice(0,index).filter(el=> el.id === cur.id)
if(!r.length){
result.push(cur)
}
return result
})
// result => [{id: 1, name: 'liming'},{id: 2, name:'xiaohong}]
三、其他数组去重的需求
1、复杂去重 加 合并重复项的某些值
如下面objArray中,根据id过滤,并且处理,将name和number的值汇总成数组
objArray = [
{ id: 1, name: "A", number: 1 },
{ id: 2, name: "B", number: 2 },
{ id: 1, name: "B", number: 3 },
{ id: 1, name: "C", number: 4 },
{ id: 1, name: "D", number: 5 },
];
let newArr = objArray.reduceRight((cur, item, index, array) => {
let curArr = cur.filter((c) => c.id === item.id);
if (curArr.length > 0) {
let nameObj = cur.find((oo) => oo.id === item.id);
nameObj.name = Array.isArray(nameObj.name)
? [...nameObj.name, item.name]
: [nameObj.name, item.name];
nameObj.number = Array.isArray(nameObj.number)
? [...nameObj.number, item.number]
: [nameObj.number, item.number];
} else {
cur.push(item);
}
return cur;
}, []);
console.log(newArr, "newArr");
//=> [{"id":1,"name":["D","C","B","A"],"number":[5,4,3,1]},{"id":2,"name":"B","number":2}]
2、 两个数组的去重
下面案例将arr2 根据arr1 的相同id 去重 , 常用 filter + some 结合去重
let arr1 = [{id:1, name:'liming'},{id:2, name:'xiaohong'}]
let arr2 = [{id:3, name:'zhangfei'},{id:2, name:'xiaohong'}]
arr2.filter(el=> arr1.some(item=> item.id === el.id))
//=> [{id: 2, name: 'xiaohong'}]
四、总结
总结: 数组去重的时候, 分为简单数组去重,及复杂的JSON数组去重, 简单的一维数组可以用new Set的唯一性去重, 还可以通过循环过程中, 通过对象的key的唯一性,将值作为key存到对象中, 判断对象中是否存在key,来判断是否要加入数组中。 或者是 通过indexOf 判断是否重复, 大体原理都比较类似, 对于复杂的JSON数组基本也是可以套简单数组的套路的, 在使用reduce、filter时可以帮我们简化代码,可以少引入几个变量, 但是可能会导致算法复杂度的提高(时间换空间), 需要在写时注意, 对于两个数组的去重, 通常是用 filter + some 两者进行配合去重
转载自:https://juejin.cn/post/7248812926176772154