数组去重

71 阅读2分钟

原始数据去重

  • 利用Set() + Array.from()
    • Set对象:是值的集合,按照插入的顺序迭代它de元素。Set中的元素只会出现一次,即Set中的元素是唯一的
    • Array.from()方法:对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
const arr = [1, 2, 2, 'abc', 'abc', true, true, false, 
            false, undefined, undefined, NaN, NaN]
            
const result = Array.from(new Set(arr))
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]

  • 利用Map()

Map对象是JS的一种数据结构,结构为键值对形式,将数组元素作为map的键存入,结合has()和set()方法判断键是否重复。

const arr = [1, 2, 2, 'abc', 'abc', true, true, false, 
            false, undefined, undefined, NaN, NaN]

fucntion removeDeuplicate(arr){
  const map = new Map()
  const newArr = []
  arr.forrEach(item =>{
   if(!map.has(item)){  // has()用于判断map是否包为item的属性值
     map.set(item,true) // 使用set()将item设置到map中,并设置其属性值为true
     newArr.push(item)
   }
  })
  return newArr
}

const result = removeDeuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]

引用数据类型去重

  • JSON.stringify()将JS对象或值转换为JSON格式字符串
  • JSON.parse()将JSON对字符串转换为JS对象
let arr = [1, 1, '2', 3, 1, 2,
    { name: '张三', id: { n: 1 }},
    { name: '张三', id: { n: 1 }},
    { name: '张三', id: { n: 2 }}
]

let arr2 = arr.map((item) => {
    return JSON.stringify(item)
})

let newArr = new Set(arr2)
newArr = Array.from(newArr).map((item) => {
    return JSON.parse(item)
})

console.log(newArr);
// [
//     1,
//     '2',
//     3,
//     2,
//     { name: '张三', id: { n: 1 } },
//     { name: '张三', id: { n: 2 } }
// ]

let arr = [1, 1, '2', 3, 1, 2,
    { name: '张三', id: { n: 1 } },
    { name: '张三', id: { n: 1 } },
    { name: '张三', id: { n: 2 } }
]

function uniqueArr (arr) {
    let res = []
    for (let item of arr) {
        let isFind = false
        for (let resItem of res) {
            if (equal(item, resItem)) {
                isFind = true
                break
            }
        }
        if (!isFind) res.push(item)
    }
    return res
}

function equal(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 (let key in v1) {
            if (v2.hasOwnProperty(key)) { // 只要v1遍历的东西,V2显示具有就再去看value
                // 有可能value也是引用类型,那就递归下
                if (!equal(v1[key], v2[key])) {
                    return false
                }
            } else {
                return false
            }
        }
        return true // 两个对象长得完全一样
    } else { // 都不是引用类型、一方是引用类型 同样这也是递归的出口
        return v1 === v2
    }
}

console.log(uniqueArr(arr));