JavaScript 数组去重

这几天整理的一下过往的文章和笔记,备份到了 Github 上,地址👉 blog

如果我的内容帮助到了您,欢迎点个 Star 🎉🎉🎉 鼓励鼓励 🙂 ~~ 👆

我希望我的内容可以帮助你。现在我专注于前端领域,但我也将分享我在有限的时间内看到和感受到的东西。


Set

Set 对象是一种新数据结构,允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

我们可以从给定数组创建一个新的 Set(),以丢弃重复的值。然后使用扩展运算符(...)将其转换回数组。

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

const unique = arr => [...new Set(arr)]
unique(arr) // [1, 2, "1", null, "", undefined, NaN, true, false]

注意,如果数值中存的是对象,值相同,但他们引用的是不同的内存地址,他会认为每个对象都是唯一的:

[...new Set([{ a: 1 }, { a: 1 }])] // [{a: 1}, {a: 1}]

// 你可以改成如下
const obj = { a: 1 }
[...new Set([obj, obj])] // [{ a: 1 }]

Set 除了和扩展运算符配合,还可以和 Array.form() 一起使用:

const unique = (arr) => Array.from(new Set(arr))

unique(arr) // [1, 2, "1", null, "", undefined, NaN, true, false]

Map

创建一个空 Map 数据结构,使用 Array.prototype.filter() 和 创建一个只包含唯一值的新数组。

const unique = arr => {
  const seen = new Map()
  return arr.filter(item => !seen.has(item) && seen.set(item, 1))
}

unique(arr) // [1, 2, "1", null, "", undefined, NaN, true, false]

Array.prototype.filter()

使用 Array.prototype.filter() 创建一个只包含唯一值的新数组。

const unique = arr => 
  arr.filter((item, index, arr) => arr.indexOf(item) === index)

unique(arr) // [1, 2, "1", null, "", undefined, true, false]

注意:该方法直接把 NaN 全局过滤了。

Array.prototype.includes()

const unique = arr => {
  const newArr = []
  arr.map(item => !newArr.includes(item) && newArr.push(item))
  return newArr
}
  
unique(arr) // [1, 2, "1", null, "", undefined, NaN, true, false]

也可以使用 Array.prototype.indexOf() 进行判断,但是存在着一个问题,该方法无法判断数组中是否含有 NaN

const unique = arr => {
  const newArr = []
  arr.map(item => newArr.indexOf(item) == -1 && newArr.push(item))
  return newArr
}

unique(arr) //  [1, 2, "1", null, "", undefined, NaN, NaN, true, false]

Array.prototype.reduce()

Array.prototype.reduce() 方法对数组中的每个元素执行一个由您提供的 reducer 函数(升序执行),将其结果组合成数组返回。

const unique = arr =>
  arr.reduce(
    (unique, item) => (unique.includes(item) ? unique : [...unique, item]),
    []
  )

unique(arr) // [1, 2, "1", null, "", undefined, NaN, true, false]

Object.hasOwnProperty()

利用 Object.hasOwnProperty 判断是否存在对象属性

const unique = arr => {
  const obj = {}
  return arr.filter(item =>
    obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true))
}

unique(arr) // [1, 2, "1", null, "", undefined, NaN, true, false]

Object 键值对

利用对象键值对不能相同名来去重

const unique = arr => {
  const obj = {}
  arr.forEach(value => {
    obj[value] = ''
  })
  return Object.keys(obj)
}

unique(arr) // ["1", "2", "null", "", "undefined", "NaN", "true", "false"]

注意两个问题

  • 数组中的任何类型都会转为字符串类型。
  • 当数组中存在相同值不同类型的数据时,会去掉其中一个。如数值 1 和字符串 '1',会去掉其中一个。

当然,为了快速开发,我们会使用一些工具库来去重。例如:

  • lodash 的 _.uniq(array)
  • Ramda 的 R.uniq(array)

更多资料

版权声明:
作者:Mr李
链接:https://www.techfm.club/p/47354.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>