JavaScript数组去重的方式

这篇具有很好参考价值的文章主要介绍了JavaScript数组去重的方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数组去重的意思就是去除数组中重复的元素,处理完后数组中所有的元素都是唯一的,本文介绍了在js中数组去重的5种方式,请往下看。

1. 利用Set对象

Set 对象

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

Set 中的特殊值

Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:

  • +0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
  • undefined 与 undefined 是恒等的,所以不重复;
  • NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个,不重复。

 由于Set中存储的值不能重复,所以我们可以利用Set对象来实现数组去重

 //简单类型数组
    const simpleArr = [1,2,2,'3','3', undefined , undefined, NaN, NaN, true, false, true, false]
    //复杂类型数组
    const complexArr = [2,2,'3','3', undefined , undefined, NaN, NaN,
      { id: 1, name: 'joke'},
      { id: 1, name: 'joke'},
      { id: 2, name: 'make'},
    ]
    let result = []
      // 方式一 利用Set去重
    console.log(Array.from(new Set(simpleArr)))    // [1, 2, '3', undefined, NaN, true, false]
    console.log(Array.from(new Set(complexArr)))   // [2, '3', undefined, NaN, {…}, {…}, {…}]

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

但是Set中不能区分复杂类型的元素,对于object类型的变量,它只是比较变量的引用,而且NaN在Set中是相等的,所以只能应用在基本类型的数组去重情况中

2. 利用Map对象

Map 对象

Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

Maps 和 Objects 的区别

  • 一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。
  • Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是。
  • Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。
  • Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
    // 方式二 利用Map()
    result = []
    let map = new Map()
    simpleArr.forEach(item=>{
      if(!map.has(item)){
        map.set(item,true)
        result.push(item)
      }
    })
    console.log(result)    // [1, 2, '3', undefined, NaN, true, false]

Map.has() : 返回一个布尔值,用于判断 Map 中是否包含键对应的值。

 Map.has()方法和Set()有点类似,也能把NaN当作相等的值,并且Map.has()方法对于object类型也只是比较其引用,所以效果和Set是相同的

3. 利用Array.indexOf()方法

indexOf() 方法可返回数组中某个指定的元素位置。

// 方式三 利用数组的indexOf方法
    result = []
    simpleArr.forEach(item =>{
      if(result.indexOf(item)===-1){
        result.push(item)
      }
    })
    console.log(result)   //  [1, 2, '3', undefined, NaN, NaN, true, false]

 这种方式不能对object类型和NaN进行判断,局限性较高。

4. 利用Array.includes()方法

includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。

   // 方式四 利用includes方法
    result = []
    simpleArr.forEach(item =>{
      if(result.includes(item)===false){
        result.push(item)
      }
    })
    console.log(result)   //  [1, 2, '3', undefined, NaN, true, false]

这个方式的思路和indexOf()大同小异,唯一不同的就是includex()能够判断NaN,底层其实是利用了isNaN()来实现的,不过也还是不能判断ojbect类型的

5. 手写一个数组去重函数

经过上面4种方式的介绍,解决基本的数组去重已经够用了,但是如果出现复杂类型的数据就不能处理了,所以需要根据实际情况手写一个数组去重函数

有这么一个数组:

const complexArr = [2,2,'3','3', undefined , undefined, NaN, NaN,
      { id: 1, name: 'joke'},
      { id: 1, name: 'joke'},
      { id: 2, name: 'make'},
    ]

里面存放着一下基本类型元素,还有object类型的元素,这些object类型的元素都有一个唯一标识属性id,那么我们就可以这样写:

 // 方式五 手写一个去重函数
    function arrayToHeavy(arr) {
      let result = []
      let objArr = []
      let isRepeat = false
      //这个循环是对基本类型的数组元素进行去重
      for (let i=0; i<arr.length; i++) {
        isRepeat = false
        // 先判断数组元素是否为对象类型,如果符合,先存入objArr中,稍后处理
        if(typeof arr[i] === 'object'){
          objArr.push(arr[i])
          continue
        }

        // 检查是否有重复的元素
        for(let j=0; j<result.length; j++) {
          //NaN 情况
          if(isNaN(arr[i]) && arr[i]!==undefined && isNaN(result[j]) && result[j]!==undefined)
            isRepeat = true
          else if(result[j] === arr[i]){
            isRepeat = true
            break
          }
        }
        // 检查完毕后,如果不存在重复元素则push
        if(!isRepeat){
          result.push(arr[i])
        }
      }
      let objResult = []
      // 这个循环是对object类型的元素进行去重
      for(let i=0; i<objArr.length; i++ ) {
        // 首先我们已经知道了这些元素都有一个唯一的id属性
        // 可以根据比较id值进行去重
        isRepeat = false
        for(let j=0; j<objResult.length; j++) {
          if(objResult[j].id === objArr[i].id){
            isRepeat = true
            break
          }
        }
        if(!isRepeat)
          objResult.push(objArr[i])
      }
      // 最后利用拓展运算符返回一个新数组
      return [...result,...objResult]
    }
    console.log(arrayToHeavy(complexArr))

这个方法关键的地方就是对NaN进行识别处理,和对object类型的元素单独提取出来迭代判断

结果:

js set去重,javascript,前端,数据结构

 结语

在js中我们可以有很多种方式进行数组去重,当然也不仅仅只有上面的那些方式,要使用哪一种方式需要视情况而定,并且当业务需求变得复杂起来可能需要我们手写一个数组去重的方法,内部逻辑也要根据数据的格式变化

希望这篇文章能够帮助到你

参考:js实现数组去重的方式(7种)_MomentYY的博客-CSDN博客_js去重方法文章来源地址https://www.toymoban.com/news/detail-732549.html

到了这里,关于JavaScript数组去重的方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 〖大前端 - 基础入门三大核心之JS篇㉔〗- JavaScript 的数组的常用方法 (一)

    当前子专栏 基础入门三大核心篇 是免费开放阶段 。 推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 大前端全栈架构白宝书专栏, 目前阶段免费开放 , 购买任意白宝书体系化专栏可加入 TFS-CLUB 私域社区。 福利:除了通过订阅\\\"白宝书系列专

    2024年02月07日
    浏览(56)
  • JavaScript数组去重,大小排序的两种方法

    方法有很多种,本文列举其中两种 声明一个数组 数组去重 1:利用ES6中的 Set 方法去重(最常用) 原理: Set数据结构中所有元素都是唯一的,没有重复 Set 本身是一个构造函数,用来生成 Set 数据结构 2:利用indexOf去重 原理: indexof() 可返回某个指定的字符串值在字符串中首

    2024年02月06日
    浏览(44)
  • 分享6个对象数组去重的方法

    大家好,关于对象数组去重的业务场景,想必大家都遇到过类似的需求吧,针对这样的需求,你是怎么做的呢。 下面我就先和大家讨论下基于对象的某个属性如何去重。 使用 filter() 方法过滤掉重复的元素,使用 findIndex() 方法判断对象是否重复,代码如下: 使用 reduce() 方法

    2024年02月16日
    浏览(47)
  • java stream去重的几种方式

    这个方法会根据元素的 hashCode() 和 equals() 方法来判断是否重复。如果是自定义的类,需要重写这两个方法。 示例: 这个方法可以根据元素的某个属性或者多个属性来去重,比如 name 或者 name+address。这个方法会使用 TreeSet 来排序元素,所以不能保持原来的顺序。 示例: 这个方

    2024年02月13日
    浏览(68)
  • 【Java】List集合去重的方式

    TreeSet可以将字符串类型的数据按照字典顺序进行排序,首字母相同则看第二位 去重前的集合元素:22 去重前的集合元素:11 去重前的集合元素:33 去重前的集合元素:66 去重前的集合元素:22 去重后的集合:[11, 22, 33, 66] 由于Set的特性是无序且不可重复,我们利用这个特性进

    2024年02月04日
    浏览(67)
  • Stream流实践(二):list 对象数组根据某字段去重的三种基本思路

    相信大家对于list简单数组的去重很熟悉了,例如以下代码 那我们来探讨下,对于list中保存为对象的数组,根据内部对象的 某一个字段 去重有什么好的思路呢? 给出一个简单的Student对象 大家学废了吗?

    2024年02月16日
    浏览(85)
  • JS-27 前端数据请求方式;HTTP协议的解析;JavaScript XHR、Fetch的数据请求与响应函数;前端文件上传XHR、Fetch;安装浏览器插件FeHelper

    早期的网页都是通过后端渲染来完成的,即服务器端渲染(SSR,server side render): 客户端发出请求 - 服务端接收请求并返回相应HTML文档 - 页面刷新,客户端加载新的HTML文档; 服务器端渲染的缺点: 当用户点击页面中的某个按钮向服务器发送请求时,页面本质上只是一些数

    2024年02月16日
    浏览(68)
  • Vue中v-if与v-for同时使用的影响和JavaScript中含对象的数组去重

    响应性和性能: v-for 指令会根据数组的每个元素创建和销毁对应的DOM元素,而 v-if 指令会根据条件来插入或移除元素。当 v-if 和 v-for 同时应用于同一个元素时,可能会影响Vue的响应性和性能。 循环内条件:当在 v-for 循环内使用 v-if 条件时,条件将针对每个循环项进行评估。

    2024年02月11日
    浏览(42)
  • JavaScript:js数组/对象遍历方法

    一、js遍历方法 序号 方法 描述 1 for 使用最基本的for循环可以遍历数组 2 for of for...of语句用来遍历可迭代对象(包括数组、Set、Map、字符串等),它可以替代传统的for循环和forEach()方法。for...of循环每次迭代都将返回一个值,而不是索引。 3 for in for...in语句用来遍历对象的可

    2024年02月09日
    浏览(56)
  • 【JS】js数组分组,javascript实现数组的按属性分组

    项目代码中有很多时候需要按一定的条件实现按属性分组 你可以使用JavaScript的 Array.prototype.reduce() 方法来将数组分组。这是一种高级的方法,它可以将数组元素组合成一个单值。在这种情况下,你可以使用它来把数组元素放到一个对象中,其中对象的键是分组的条件,值是所

    2023年04月08日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包