JavaScriptJavaScript·

JS实现数组去重的七种方法

Publié à 2024-08-28 23:24:49Vu 38 fois
Article professionnel
Réimpression Veuillez indiquer la source

JS数组去重的方式

例:将下面数组去除重复元素(以多种数据类型为例)

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

1.利用Set()+Array.from()

Set对象:是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即Set中的元素是唯一的

Array.from() 方法:对一个类似数组可迭代对象创建一个新的,浅拷贝的数组实例。

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

注意:以上去方式对NaNundefined类型去重也是有效的,是因为NaNundefined都可以被存储在Set中, NaN之间被视为相同的值(尽管在js中:NaN !== NaN)。

2.利用两层循环+数组的splice方法

通过两层循环对数组元素进行逐一比较,然后通过splice方法来删除重复的元素。此方法对NaN是无法进行去重的,因为进行比较时NaN !== NaN
function removeDuplicate(arr) {
  let len = arr.length
  for (let i = 0; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      if (arr[i] === arr[j]) {
        arr.splice(j, 1)
        len-- // 减少循环次数提高性能
        j-- // 保证j的值自加后不变
      }
    }
  }
  return arr
}

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

3.利用数组的indexOf方法

新建一个空数组,遍历需要去重的数组,将数组元素存入新数组中,存放前判断数组中是否已经含有当前元素,没有则存入。此方法也无法对NaN去重。
  • indexOf() 方法:返回调用它的String对象中第一次出现的指定值的索引,从 fromIndex 处进行搜索。如果未找到该值,则返回 -1。
function removeDuplicate(arr) {
  const newArr = []
  arr.forEach(item => {
    if (newArr.indexOf(item) === -1) {
      newArr.push(item)
    }
  })
  return newArr // 返回一个新数组
}

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

4.利用数组的includes方法

此方法逻辑与indexOf方法去重异曲同工,只是用includes方法来判断是否包含重复元素。
  • includes()方法:用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。
function removeDuplicate(arr) {
  const newArr = []
  arr.forEach(item => {
    if (!newArr.includes(item)) {
      newArr.push(item)
    }
  })
  return newArr
}

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

注意:为什么includes能够检测到数组中包含NaN,其涉及到includes底层的实现。如下图为includes实现的部分代码,在进行判断是否包含某元素时会调用sameValueZero方法进行比较,如果为NaN,则会使用isNaN()进行转化。

具体实现可参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

简单测试includes()NaN的判断:

const testArr = [1, 'a', NaN]
console.log(testArr.includes(NaN)) // true

5.利用数组的filter()+indexOf()

filter方法会对满足条件的元素存放到一个新数组中,结合indexOf方法进行判断。
  • filter() 方法:会创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
function removeDuplicate(arr) {
  return arr.filter((item, index) => {
    return arr.indexOf(item) === index
  })
}

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

注意:这里的输出结果中不包含NaN,是因为indexOf()无法对NaN进行判断,即arr.indexOf(item) === index返回结果为false。测试如下:

const testArr = [1, 'a', NaN]
console.log(testArr.indexOf(NaN)) // -1

6.利用Map()

Map对象是JavaScript提供的一种数据结构,结构为键值对形式,将数组元素作为map的键存入,然后结合has()set()方法判断键是否重复。
  • Map 对象:用于保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值。
function removeDuplicate(arr) {
  const map = new Map()
  const newArr = []

  arr.forEach(item => {
    if (!map.has(item)) { // has()用于判断map是否包为item的属性值
      map.set(item, true) // 使用set()将item设置到map中,并设置其属性值为true
      newArr.push(item)
    }
  })

  return newArr
}

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

注意:使用Map()也可对NaN去重,原因是Map进行判断时认为NaN是与NaN相等的,剩下所有其它的值是根据 === 运算符的结果判断是否相等。

7.利用对象

其实现思想和Map()是差不多的,主要是利用了对象的属性名不可重复这一特性。
function removeDuplicate(arr) {
  const newArr = []
  const obj = {}

  arr.forEach(item => {
    if (!obj[item]) {
      newArr.push(item)
      obj[item] = true
    }
  })

  return newArr
}

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


原文链接:https://blog.csdn.net/qq_52732369/article/details/121877897

Section des commentaires

Pas encore de commentaire, ajoutez le premier.

弦圈热门内容

Vue.js与Nuxt.js的区别

Vue.js与Nuxt.js都是前端的两个框架,Vue.js的项目属于单页应用,而Nuxt.js是基于Vue.js的服务端渲染通用框架。单页应用简称SPA,指的是前端代码将会在浏览器端被浏览器渲染。这对SEO优化不利,搜索引擎爬虫,会爬到空的网页。在Vue项目中,Vue会将JS交给浏览器渲染因此,结果是查看源代码没有别的东西,搜索引擎爬虫也基本只能看到这些,于是便直接下一个了,不会等你渲染。而服务端渲染,简称SSR,正是该问题的解决方案。前端代码会先在Node.js服务端渲染,然后再交给浏览器进行“二次渲染”。Nuxt.js则是Vue.js的SSR通用解决方案。前端代码经过服务端渲染后,能让搜索引擎爬虫看到完整的网站,同时查看源代码也能看到完整的代码。服务端渲染能提高网站渲染速度,降低白屏时间。同时,因为要同时运行Node.js服务端,这增加了服务器的负载。在Nuxt.js中,可以设置部分页面SSR,部分页面则是SPA,这样能降低服务器的资源耗费。对于静态网站,可以使用预渲染替代服务端渲染。预渲染,简称SSG,指提前渲染静态的html,提高页面响应。SSG一般适用于文档、个人博客等场景 ...

Linux是什么?Linux简介

1. Linux操作系统这个词严格来说是不对的,因为Linux其实只是个宏内核,Linux的各个发行版才算得上是真正的操作系统。相比于Windows和unix,Linux是免费开源的(虽然某些发行版是付费的),其实Linux就诞生于这样的背景下。Linus还是学生的时候,他的一个老师因为不想用付费的unix教学,因此自己写了一个操作系统,免费开源。而Linus根据这个操作系统,自行开发出Linux系统。值得一提的是,手机安卓系统用的是Linux内核,而苹果系统用的则是unix系统的一个分支。在电脑的操作系统中,目前市场占比最高的仍然是Windows系统,Windows的图形界面相较于Linux的重命令行对于用户更友善,更易使用。而在服务器的操作系统中,很多服务器都使用Linux系统,因为Linux占的内存更小,相较于Windows更轻,服务器跑久了也不容易卡。同时,服务器基本上都是纯命令行的,因为安装桌面占用空间,因此使用纯命令行的Linux更合适,据说当初Linus就是不喜欢图形界面的。其实Linux也是可以安装图形环境的(即桌面),如GNOME、Xfce,但是有些云服务器,比如我现 ...

cover

如果假设地心人存在,就能解释为什么至今没有发现外星人

说到地心人这类阴谋论(斯诺登揭秘:地下世界真相,地心人真的存在吗?),原本应该当乐子看看就算了。但是如果假设地心人存在,并且是比地表人更高程度的文明,那么就能得出一些有趣的结论,能够解释以下几个问题。为什么至今没有发现外星人👽?为什么人类一直向外太空发射信息,向外星人问好,却没有回应?为什么不怕黑森林法则?​说到底还是因为人类太弱小了,人类科技发展到如今的程度,对整个地球的探索都只限于薄薄的表面。人类对地下最深处的探索记录,于整个地球而言,只相当于在一个蛋壳表面划掉一层皮。毕竟连最外面的地幔都只是钻了个小口。我们对于地底结构的认识很大程度上依赖于地震波。在这里我们展开想象,既然地心人假设存在,且拥有高度发达的文明,那么应该有相应的手段在地底完全隐匿起来,不被外面的人发现,且不会被地震波所暴露,甚至想在地底藏匿,避免地震波的影响本来就是一个前提条件。​上面论述中有个关键词是隐匿、藏匿,为什么地心人要藏起来呢?答案很简单,因为黑森林法则。有句话叫做闷声发大财,如果一个人刚刚发展起来,那么他一定会尽量低调,不被厉害的人盯上,保全自己。同样,一个文明刚刚发展起来,到了一个相对可观的程度(比如超 ...

cover

世界婴儿危机,我们要被婴儿淹没了吗?

在遥远的未来,一场前所未有的婴儿危机席卷全球,仿佛人类即将被这些无辜的小生命淹没。而这场危机的源头,竟然源自一个被誉为“世界第一X大国”的泡菜国。泡菜国因“伟哥河”的奇特现象,人口暴增,幼儿园爆满,无数孩子提前继承了家产。樱花国因难民涌入,出生率飙升,政府欢呼经济新曙光,半场开香槟。然而,樱花国很快因人口爆炸而面临前所未有的社会压力。驻樱花米军被迫撤离,并“意外”留下氢弹发生爆炸,人们以为能暂时缓解这场危机,但出乎所有人意料的是,这些新生儿们似乎拥有了对核辐射的免疫力。他们组成了一支支无意识的婴儿大军,跨越海洋,向世界各地迁徙。鹰酱国成为了他们新的目标,面对这些无辜又强大的生命,人们陷入了恐慌和混乱。

cover

宇宙真的是被造物主设计出来的吗?如果是,那么造物主是怎么样的存在?

我们所生活的宇宙是一个运转极其严密而又无比神秘的空间,时间,物质构造的综合体。每当我思考宇宙时,总有一个疑问随之而来,也挥之不去,这个疑问就是;我们的宇宙如此运行严密,如此奇巧,这到底是怎么形成的?难道宇宙的背后真的有造物主吗?难道宇宙真的是造物主设计出来的吗?图片来自网络在古老的人们对上天的崇拜和神话传说,到宗教文化,其都把宇宙的诞生归结于造物主的创造。当科学从最初的研究造物主存在的可能性,发展至当下科学形成一整套逻辑严密的学科,造物主似乎依然没有漏出其真实面容。图片来自网络对于宇宙是否是造物主所为,这个疑问始终伴随着我,只要我一思考宇宙的终极问题时,这个疑问总是第一时间跳出来,而我却无法回避,于是我抛开其它问题,死磕这个问题。终于在我付出了近4000个日夜的思考,终于对这个问题有了属于我自己的答案。图片来自网络我认为,所谓的造物主,其真实身份应该是宇宙运行法则,而宇宙运行法则是由宇宙最原始的构成条件,在其构成条件各自所存在的自性之间的相互作用而形成的自然反应所形成的。因此我认为我们宇宙的造物主就是;宇宙的构成材料和宇宙的运行法则。宇宙运行法则就是宇宙的造物主,他存在在宇宙之中的每个 ...