Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 528|回复: 0

js数组去重解决方案

[复制链接]
  • TA的每日心情
    奋斗
    4 天前
  • 签到天数: 802 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726006
    发表于 2021-7-9 11:49:55 | 显示全部楼层 |阅读模式

    js数组去重是前端面试中经常被问的题目,考察了面试者对js的掌握,解决问题的思路,以及是否具有专研精神。曾经一位前端界大神告诉我,解决问题的方式有很多种,解决问题时多问问自己还有没有其他的方法,探求最优解决方案才能学到更多
    如果,这篇文章有幸被您阅读,文中出现的错误,或者您有其他的解决方案请在评论区告诉我,谢谢。


    方案一

     /**
       * 1.构建一个新数组
       * 2.遍历目标数组,依次取出每一个元素
       * 3.将取出的元素与新数组里面的所有元素进行比较,
       *    如果没有出现 -> 该元素添加到新数组中,
       *    如果出现  -> 处理下一个目标数组元素
       * */
      function distinct(arr) {
        console.time();    //跟踪方法的占用时长
        var result = [];    // 构建结果数组result
        for (var i = 0, len = arr.length; i < len; i++) {
          for (var j = 0, rlen = result.length; j <= rlen; j++) {
            if (arr === result[j]) {
              break;
            }
            if (j == result.length) {
              result.push(arr);
            }
          }
        }
        console.timeEnd();
        return result;
      }
    
    方案优点:
    • 结果数组与目标数组的顺序保持一致
    • 思路简单,兼容性好
    方案缺点:
    • 速度慢

    方案二

    /**
       *1.目标数组排序
       *2.遍历目标数组,检测数组中的第i 个元素与结果数组中最后一个元素是否相同,如果不同,则将该元素添加到结果数组中
       * */
      function distinct(arr) {
        console.time();
        var result = [];
        arr = arr.sort();
        for (var i = 0, len = arr.length; i < len; i++) {
          if (arr !== result[result.length - 1]) {
            result.push(arr)
          }
        }
        console.timeEnd();
        return result;
      }
    
    方案优点:
    • 方案中先排序,后遍历,速度比方法一快
    方案缺点:
    • 方案中使用了数组排序sort,打乱了原有顺序

    Tips:数组排序

    js中提供了数组排序方法sort,使用时需要注意以下几点:

    1. 调用sort方法时改变了目标数组本身,非生成新数组
    2. sort方法默认按照字符顺序进行排序,不过提供了回调方法,可以自定义排序规则

    现有一数组arr:1,11,23,56,3,4,5,7,562,67

    按字符排序
    arr.sort() // 1, 11, 23, 3, 4, 5, 56, 562, 67, 7
    
    按数字大小:正序
    arr.sort((a,b) => a-b) // 1, 3, 4, 5, 7, 11, 23, 56, 67, 562
    
    按数字大小:倒序
    arr.sort((a,b) => b-a) // 562, 67, 56, 23, 11, 7, 5, 4, 3, 1
    

    方案三

    /**
       * 利用ES6的 数据结构SET的无重复值特性
       * Array.from 将类数组转换成数组
       * */
      function distinct3(arr) {
        console.time();
        var result = Array.from(new Set(arr));
        console.timeEnd();
        return result;
      }
    
    方案优点:
    • 代码简洁,执行速度快
    方案缺点:
    • ES6语法,使用时需要考虑兼容性问题

    方案四

     /**
       * 利用对象属性无重复的特点
       * 遍历目标数组,将值设置为对象属性
       * Object.keys 将对象的所有属性提取成一个数组
       * */
      function distinct(arr) {
        console.time();
        var result = {};
        for (var i = 0, len = arr.length; i < len; i++) {
          result[arr] = '';
        }
        result = Object.keys(result);
        console.timeEnd();
        return result;
      }
    
    方案优点:
    • 速度快
    方案缺点:
    • 1 与 '1' 无法区分
    • 结果数组中的值全部为字符串
    • 占内存,相当于利用空间换时间

    方案五

    /**
       * Array.filter 数组过滤函数,只保留符合条件的值
       * indexOf 查找元素第一次出现的位置,所有第1次之后查找的元素位置都不符合条件
       * */
      function distinct(arr) {
        console.time();
        var result = arr.filter(function (elem, index, self) {
          return self.indexOf(elem) === index;
        });
        console.timeEnd();
        return result;
      }
    

    测试

    随机生成包含10000个数字的数组

    function random() {
        var a = [];
        for (var i = 0; i < 10000; i++) {
          a.push(Math.ceil(i * Math.random()))
        }
        return a;
      }
    

    现在执行上述去重方法,取5次测试结果的平均值:

    方法一 方法二 方法三 方法四 方法五
    第一次 91.281 7.921 4.36 2.038 68.856
    第二次 104.492 7.519 2.267 1.328 70.555
    第三次 105.937 8.874 1.804 1.680 73.020
    第四次 100.524 5.287 2.602 1.573 85.129
    第五次 106.612 8.990 1.615 1.963 79.115
    平均 101.769 7.718 2.529 1.716 75.335

    从执行速度来看,方法四 < 方法三 < 方法二 < 方法五 < 方法一
    方法四最快,方法一最慢。但是五种方法各有优缺点,使用时要根据实际情况选择适合的方案。


    写在最后

    本篇文章旨在学习分享和记录,并不是说数组去重只有这五种方法,如果文章中出现了错误,或者您有更好的解决方案,麻烦您在评论区告知我,谢谢。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-15 02:00 , Processed in 1.099471 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表