一 数组去重有几种方法

1.1 利⽤Set()+Array.from()

这种方法对NaN和undefined类型去重也是有效的,是因为NaN和undefined都可以被存储在Set 中, NaN之间被视为相同的值,但是无法去重引用类型的数据,比如对象数组

let arr = [
  1,
  2,
  3,
  undefined,
  null,
  NaN,
  '1',
  1,
  undefined,
  null,
  NaN,
  '1',
  16,
  18,
]

let uniqueArr = Array.from(new Set(arr))
console.log('🚀 ~~- uniqueArr:', uniqueArr)

1.2 利⽤两层循环+数组的splice⽅法

此⽅法对NaN是⽆法进⾏去重的,因为进⾏⽐较时NaN !== NaN

//双重循环去重
const handleRemoveRepeat = (arr) => {
  for (let i = 0, len = arr.length; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      if (arr[i] === arr[j]) {
        arr.splice(j, 1)
        j--
        len--
      }
    }
  }
  return arr
}

let uniqueArr1 = handleRemoveRepeat(arr)
console.log('🚀 ~~- uniqueArr1:', uniqueArr1)

1.3 利⽤数组的indexOf⽅法

新建⼀个空数组,遍历需要去重的数组,将数组元素存⼊新数组中,存放前判断数组中是否已经含有当前元素,没有则存⼊。此⽅法也⽆法对NaN去重

  • indexOf() ⽅法:返回调⽤它的对象中第⼀次出现的指定值的索引
const handleRemoveRepeat1 = (arr) => {
  let uniqueArray = []
  for (let i = 0; i < arr.length; i++) {
    if (uniqueArray.indexOf(arr[i]) === -1) {
      // 如果当前元素在uniqueArray中不存在,则添加进去
      uniqueArray.push(arr[i])
    }
  }
  return uniqueArray
}

let uniqueArr2 = handleRemoveRepeat1(arr)
console.log('🚀 ~~- uniqueArr2:', uniqueArr2)

1.4 利⽤数组的includes⽅法

  • 此⽅法逻辑与indexOf⽅法去重异曲同⼯,只是⽤includes⽅法来判断是否包含重复元素
const handleRemoveRepeat3 = (arr) => {
  let uniqueArray = []
  for (let i = 0; i < arr.length; i++) {
    if (!uniqueArray.includes(arr[i])) {
      uniqueArray.push(arr[i])
    }
  }
  return uniqueArray
}

let uniqueArr3 = handleRemoveRepeat3(arr)
console.log('🚀 ~~- uniqueArr3:', uniqueArr3)

1.5 利⽤数组的filter()+indexOf()

  • 输出结果中不包含NaN,是因为indexOf()⽆法对NaN进⾏判断
const handleRemoveRepeat4 = (arr) =>
  arr.filter((item, index) => arr.indexOf(item, 0) === index)

let uniqueArr4 = handleRemoveRepeat4(arr)
console.log('🚀 ~~- uniqueArr4:', uniqueArr4)

1.6 对象数组去重

对象数组去重用上面的方法就不太管用了,需要使用下面的几种方法:

  • 使用map
function handleRemoveRepeat5(arr) {
  const result = []
  const mapList = new Map()
  arr.forEach((item) => {
    if (!mapList.has(item.id)) {
      result.push(item)
      mapList.set(item.id, true)
    }
  })
  return result
}

let uniqueArr5 = handleRemoveRepeat5(arr)
console.log('🚀 ~~- uniqueArr5:', uniqueArr5)
  • 使用reduce
let unique = (arr, property) => {
  const s = new Set()
  if (property) {
    return arr.reduce((prev, curr) => {
      let item = null
      if (typeof property === 'string' && property) {
        item = curr[property]
      } else {
        item = typeof curr === 'object' ? JSON.stringify(curr) : curr
      }
      if (!s.has(item)) {
        s.add(item)
        prev.push(curr)
      }
      return prev
    }, [])
  }
}

let result = unique(arr, 'id')
console.log('🚀 ~~- result:', result)
  • 使用some方法
const sxz = 'id'
let unique = (arr) => {
  return arr.reduce(
    (pre, cur) =>
      pre.some((item) => item[sxz] == cur[sxz]) ? pre : [...pre, cur],
    []
  )
}

let unique1 = unique(arr)
console.log('🚀 ~~- unique1:', unique1)