数组去重以及深拷贝

122 阅读1分钟

数组去重

数组元素为非对象

  • 两层循环
const arr = [3,3,4,3,'a','a']
function removeDuplicate(array){
    let len = array.length
    for(let i =0;i<len;i++){
        for(let j=i+1;j<len;j++){
            if(array[i] === array[j]){
                array.splice(j,1)
                len--
                j--
            }
        }
    }
    return array
}

console.log(removeDuplicate(arr));
  • 使用 Set() MDN Set() 解释,Set对象是值的集合,你可以按照插入的顺序迭代它的元素。Set 中的元素只会出现一次,即 Set 中的元素是唯一的。
const arr = [3,3,4,3,'a','a']

function removeDuplicate1() {
    return [...new Set(arr)]
}

console.log(removeDuplicate1(arr));
  • 使用 filter + indexOf
const obj1 = {a: 1}
const arr = [3,3,4,3,obj1,obj1,'a','a']

function  removeDuplicate2() {
    return arr.filter((value,index)=>arr.indexOf(value) === index)
}
console.log(removeDuplicate2(arr));
// 输出结果 [ 3, 4, { a: 1 }, 'a' ]
  • 不能创建新的数组 由于 filter 和 map 两个方法都会产生新的数组,要求只能修改原数组,不能产生新的数组。
const obj1 = {a: 1}
const arr3 = [3,3,4,3,obj1,obj1,'a','a']

function  removeDuplicate3() {
    let set = new Set()
    for( let i = 0;i<arr3.length; i++ ){
        if(!set.has(arr3[i])){
            set.add(arr3[i])
        }else{
            arr3.splice(i,1)
            i--
        }
    }
}
removeDuplicate3(arr3)
console.log(arr3);

数组元素含有对象

  • 去掉重复对象 由于 Set() 不能判断两个对象内容是否完全相等,所以需要将对象处理成字符串,才能被 Set() 处理。
const obj1 = {a: 1}
const arr = [3, 4, 3, obj1,obj1,{a: 1}, {a: 1}, [3, 4, 5], [3, 4, 5], "a", "a"]

function removeDuplicate4(Array) {
    let set = new Set()
    return arr.filter(value => {
        if (typeof value === 'object' && value !== null) {
            value = JSON.stringify(value)
        }
        if (set.has(value)) return false
        set.add(value)
        return true
    })
}

console.log(removeDuplicate4(arr));
// 输出结果 [ 3, 4, { a: 1 }, [ 3, 4, 5 ], 'a' ]

  • 多对象去掉重复字段
let arr = [{id:1, value:"react"},{id:2, value:"react"},{id:3, value:"vue"}]
function removeDuplicate5(arr) {
    let set = new Set()
    return arr.filter(item => !set.has(item.value) && set.add(item.value))
}

console.log(removeDuplicate5(arr));
// 输出结果  [ { id: 1, value: 'react' }, { id: 3, value: 'vue' } ]

深拷贝

  • 深拷贝 如果只是简单想要获得一个深拷贝之后的对象,可以使用下面比较【投机取巧】的方法。
let obj1 = {a: 1, b: 2, c: {ccc: 333}, d: [1, 2, 3, 4]}
let obj2 = [1, {a: 1}, [3, 4]]

// 投机取巧的方法
let objCopy3 = JSON.parse(JSON.stringify(obj1))
console.log(objCopy3);

// 面试可能想要的方法
function deepCopy(objOrArr) {
    let ret = Array.isArray(objOrArr) ? [] : {}
    for(let key in objOrArr){
        if(typeof objOrArr[key] !== 'object' ||  objOrArr[key] === null){
            ret[key] = objOrArr[key]
        }else{
            ret[key] = deepCopy(objOrArr[key])
        }
    }
    return ret
}

let objCopy1 = deepCopy(obj1)
let objCopy2 = deepCopy(obj2)
console.log(objCopy1);
console.log(objCopy2);
  • 深拷贝一个函数
function sum(a, b) {
    return a + b
}

function deepCopyFunc(fn) {
    return fn.bind(null)
}

let sum2 = deepCopyFunc(sum)
console.log(sum2(2, 3));       // 输出结果 5
console.log(sum2 === sum);     // 输入结果 false