彻底搞定各种数组去重需求

简介: 前言数组去重是面试时候常考的,我们日常工作中,也经常会遇到, 接下来就归纳总结几种数组去重的方案, 在我们开发和面试的时候可以得心应手,分类在实现数组去重之前我们我们简单进行一下分类, 数组去重,我们一般 分为单个数组去重 和多个数组交叉去重, 接下来我们就从单个数组开始

前言

数组去重是面试时候常考的,我们日常工作中,也经常会遇到, 接下来就归纳总结几种数组去重的方案, 在我们开发和面试的时候可以得心应手,

分类

在实现数组去重之前我们我们简单进行一下分类, 数组去重,我们一般 分为单个数组去重 和多个数组交叉去重, 接下来我们就从单个数组开始

一、简单的数组去重

简单数组去重经常是普通数组进行去重, 我们常用的是利用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 两者进行配合去重

相关文章
|
1月前
|
存储 前端开发 索引
【面试题】数组去重的五种方法(必会)
【面试题】数组去重的五种方法(必会)
|
1月前
|
存储 前端开发 索引
【面试题】数组去重的五种方法
【面试题】数组去重的五种方法
|
6天前
|
JavaScript 索引
这么多数组方法,你掌握了么?
这么多数组方法,你掌握了么?
|
9月前
|
存储 索引
事件委托,数组去重
事件委托,数组去重
195 0
|
10月前
数组去重-数组对象去重
数组去重-数组对象去重
34 0
|
1月前
|
索引
javaScripe如何进行数组去重。
javaScripe如何进行数组去重。
17 0
|
11月前
|
索引
数组方法大全
数组的方法 1. join (原数组不受影响) 该方法可以将数组里的元素,通过指定的分隔符,以字符串的形式连接起来。 返回值:返回一个新的字符串
|
10月前
|
前端开发
前端数组方法splice
前端数组方法splice
70 0
|
JavaScript