1

前端数组去重已经不是一个新鲜的话题了,关于去重的方式也是有很多姿势,本文介绍几种常用的去重方式。
image

  • for - of 循环去重
let arr = [1, 2, 3, 3, 4,1]
function unique(arr) {
  let tempt = [], obj = {}
  for (let item of arr) {
    if (!obj[item]) {
      obj[item] = item
      tempt.push(item)
    }
  }
  return tempt
}
console.log(unique(arr)) // [1, 2, 3, 4]
  • ES6两种去重方式
// 方式1
Array.from(new Set(arr))

// 方式2
[...new Set(arr)]
  • filter去重
// 该方式对数组循环了两次,不建议使用
let re = arr.filter((item, index) => {
  return arr.indexOf(item) === index
})
  • reduce去重
let newArr = arr.reduce((pre,cur)=>{
    if(!pre.includes(cur)){
         pre.push(cur)
    }
    return pre
},[])

那么问题来了,==如果目标数组存在相同的引用类型元素呢?==我们把arr换成[5, '1', 5, 1, 2, {}, {}, /a/, /a/]

  • 那么for-of返回值为
[ 5, '1', 2, {}, /a/ ]  // 未区分string类型的1和number类型的1
  • 其余几种方式
[5,  '1', 2,   {}, {}, /a/, /a/] // 引用类型的元素未能去重(这里看怎么理解,两个值相同的引用类型不一定相同,两者所指向不一定相同)
由上可见,似乎是每种方式都有一些缺陷,需要一种完善的方式来对这些问题单独处理
  • 去重完整版
Array.prototype.unique = function () {
  if (this) {
    let obj = {}, tempt = []
    this.forEach(item => {
    // 通过类型 + 值来确定唯一性
      if (!obj.hasOwnProperty(typeof item + item)) {
        obj[typeof item + item] = item
        tempt.push(item)
      }
    })
    return tempt 
  }
}
let arr = [5, '1', 5, 1, 2, {}, {}, /a/, /a/]
console.log(arr.unique()) // [ 5, '1', 1, 2, {}, /a/ ]
上面的方法只是一种思路,其他法式还有待各位观众姥爷发掘,如有错误,欢迎大家留言指正

因果
3 声望0 粉丝

哼哼,就不给你说