数组去重

121 阅读2分钟

前言

数组去重也是面试很经典的一个问题,接下来我们聊聊怎么去重以及手写一个去重方法.

set

我们可以利用set这一数据结构来帮助我们去重

let arr=[2,4,5,3,7,9,6,3]

let set=new Set(arr)

console.log(set)

image.png

但是这个方式只能帮我们去重原始数据类型,引用数据类型就不行,因为引用数据类型在堆里存储的是引用地址,即使长的一样但他们的引用地址是完全不同的

let arr = [
    { id: 1, name: "张三" },
    { id: 2, name: "李四" },
    { id: 3, name: "王五" },
    { id: 4, name: "赵六" },
    { id: 1, name: "张三" },
]


let set=new Set(arr)

console.log(set)

image.png

手写去重函数

function unique(arr) {
  let res=[]
  for(let i=0;i<arr.length;i++){
    let isfind=false;
    for(let j=0;j<res.length;j++){
      if(equals(arr[i],res[j])){
        isfind=true;
        break;
      }
    }
    if(!isfind){
      res.push(arr[i]); 
    }
  }
  return res;
}

function equals(v1,v2){
  if((typeof v1==="object" && v1 !==null)&&(typeof v2==="object" && v2 !==null)){
     if(Object.keys(v1).length!==Object.keys(v2).length){
       return false;
     }
     for (const key in v1) {
        if(v2.hasOwnProperty(key)){
          if(!equals(v1[key],v2[key])){
            return false; 
          }
        }else{
          return false;
        }
     }
     return true;
  }else{
    return v1===v2;
  }
}

unique部分:

首先创建一个空数组,循环遍历数组,数组的每一项和结果数组的每一项进行对比(equals函数进行比对),如果相同则isfind更改状态,如果没有则放入结果数组中,最后返回结果数组

equals部分:

向将传入的两个值进行数据类型判断,如果两个都是引用数据类型才会走下面的判断,否则说明他们至少有一个是原始数据类型,return v1===v2;在判断都是引用数据类型后判断他们key的个数是否相同,不同则返回false;遍历v1对象,如果v2没有相同的key返回false,如果有则进行下一次遍历;如果key对应的value是引用数据类型则进行递归判断;当循环结束之后还没有返回fasle就认定v1v2完全一样,返回true

image.png