范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

深入分析数组去重

  大家好,我是前端西瓜哥。
  数组去重  是常见的面试考点,所以我就试着深入学习一下。网上也有很多数组去重的文章,但我自己觉得分析的不够深入,其实其中很多的实现都是重复的,可以归为一类,比如 双重循环法 和 indexOf法 的本质都是双重循环,故写下此文,做进一步的总结,同时加深理解。  1. 双重循环
  这种方法就很直接,很好理解。那就是创建一个新的空数组,每次我们会从原数组中取出一个元素,拿它和新数组的元素进行一一比较。
  如果在新数组没发现和取出元素相等的元素,就将其放入这个新数组中;如果发现有和取出元素相等的元素,不放入新数组中。
  当原数组中的数组全都取出来时,这个新数组就是去重后的所有数据了。
  这种数组去重的实现的时间复杂度是 O(n^2)。  const unique = arr => {     let res = [];     for (let i = 0, len = arr.length; i < len; i++) {         let j = 0, len2 = res.length;         for (; j < len2; j++) {             if (arr[i] === res[j]) break;         }         if (j == len2) res.push(arr[i]);  // j == len2 表示没有执行 break。     }     return res; }
  当然这里的第一个循环可以改为   forEach()    方法,第二个 for 循环可以改为使用  includes()    或者  indexOf()    方法,时间复杂度没什么变化,不过代码更简洁。 const unique = arr => {     let res = [];     arr.forEach(item => {         if (!res.includes(item)) res.push(item);      })     return res; }  2. 查找元素第一次出现的位置
  从后往前遍历数组,检测元素第一次出现的位置是否为当前元素的位置。如果不是,说明有重复,移除当前元素;如果没有,就不移除。
  之所以从后往前遍历,是因为我们要搬移元素(其实就是 splice)。
  当然你也可以选择从前往后遍历,不过这样的话,如果遍历时当前元素被移除了,那么移除元素后的 arr[i] 对应的元素其实是原来 arr[i+1],因此此时 i 不能自增,且结束的条件要改为   i == len-1   ,就很麻烦。
  这种写法不需要创建新的数组,空间复杂度为 O(1)。  const unique = arr => {     for (let i = arr.length - 1; i >= 0; i--) {         for (let j = 0; j < i; j++) {             if (arr[j] === arr[i]) arr.splice(i, 1);         }     }     return arr; }
  这里的代码实现是尽量减少时间复杂度的。
  说个题外话,其实上面这里还可以再优化一下,因为我们这里的元素搬移并不是一次性搬移到最终的位置上的。优化思路是先标记要所有要删除的元素索引,然后从前往后遍历数组,每遇到第 m 个删除索引,后面的元素就覆盖掉它们往前第 m 位的数组元素,这里就不实现了,也就随便提一下。
  如果改为配合使用   filter()    和  includes()    方法的话,我们可以让代码可读性更好一些(性能会稍微下降,因为 incluedes 会遍历整个数组),具体实现就不写了。 3. 排序后去重
  排序算法有很多种,我们就用 js 自带的排序算法吧。顺带一说,v8引擎 的   sort()    方法在数组长度小于等于10的情况下,会使用插入排序,大于10的情况下会使用快速排序。
  排(guai)好(guai)序(zhanhao)后,检查前后两个相邻元素,如果当前元素和前面的元素不相等,才将当前元素放入新数组中。  const unique = arr => {     if (arr.length < 2) return arr;      arr.sort();     let r = [arr[0]];     for (let i = 1, len = arr.length; i < len; i++) {         if (a[i] !== a[i - 1]) r.push(a[i]);     }     return r; }
  这种去重局限性非常大。
  它不适用于对象,因为对象不适合进行排序。sort() 的默认排序顺序是根据字符串Unicode码点进行排序,貌似会把对象转为字符串再进行排序,一般的对象都会转为 "[object Object]",无法保证两个引用同一个对象的变量能相邻排列。  4. 使用散列表
  散列表,在 JavaScript 中是通过对象来实现的。散列表的优点是,一般情况下读取数据的时间复杂度是 O(1)。
  但 js 的对象的键只能为字符串类型,不过可以考虑使用 ES6 新增的 Map 数据结构,它允许使用任何类型的值作为键。
  下面的实现使用的是普通对象作为散列表,有很大的局限性,无法对 js对象 进行去重(对象都会转为类似 [object Object] 的字符串)。
  另外,对于js对象来说,a["1"] 和 a[1] 是相等的,因为1会转换为"1",这样就无法分辨出 1 和 "1",从而错误地在去重过程中丢弃其中的一个元素,所以我做了简单地改良,键名使用的不是   arr[i]    而是  typeof(arr[i]) + arr[i]   。 const unique = arr => {     let r = [];     let map = {};     for (let i = 0, len = arr.length; i < len; i++) {         const item = arr[i];         if (!map[typeof(item) + item]) {             r.push(arr[i]);         }         map[typeof(item) + item] = true;      }     return r; } 
  这种实现方式,时间复杂度可以达到 O(n)。
  如果考虑对象也能去重,可以考虑使用 ES6 的 Map。  5. ES6 的 Set
  ES6 提供了新的数据结构。Set 实例会认为两个 NaN 是相等的(尽管 NaN !== NaN),并认为两个对象是不等的(当然这里两个对象的意思,表示的是两个指向不同内存空间的引用类型变量)。
  并不太了解 Set 的源码实现,就不分析性能了。  const unique = arr => {     return Array.from(new Set(arr)) }
  非常简洁,如果你的运行环境支持 ES6,或者可以编译成 ES5,我很推荐使用这个去重方案。  考虑 NaN 的去重
  如果要考虑 NaN 的去重,就需要稍微对代码进行一些修改。
  简单来说就是,判断 item 是否为 NaN,然后检查返回的数组中是否已有 NaN。如果有,放入数组;否则不放入。  const unique = arr => {     let res = [];     let hasNaN = false;     arr.forEach(item => {         if(!hasNaN && Number.isNaN(item)) {             res.push(item);             hasNaN = true         }else if (!res.includes(item)) {             res.push(item);          }     })     return res; }  lodash 如何实现去重
  简单说下 lodash 的 uniq 方法的源码实现。
  这个方法的行为和使用 Set 进行去重的结果一致。
  当数组长度大于等于 200 时,会创建 Set 并将 Set 转换为数组来进行去重(Set 不存在情况的实现不做分析)。
  当数组长度小于 200 时,会使用类似前面提到的 双重循环 的去重方案,另外还会做 NaN 的去重。  总结
  一般来说,在开发中,要进行去重的数组并不是很大,不必太考虑性能问题。所以在工程中,为了不把简单的问题复杂化中,建议使用最简洁的 ES6 的 Set 转数组的方案来实现。
  当然具体问题具体分析,要根据场景选择真正合适的去重方案。
  另外,其实 "相等" 有很多种定义,ES6 中就有四种相等算法,这里就不多说了,有兴趣的话可以看看这篇文章:JavaScript 中的相等性判断。依旧是根据场景选择合适的相等算法。

以MiniLED技术为矛,冲击全球第一!TCLMiniLED战略发布8月26日,TCL在深圳召开了主题为看见更有远见TCLMiniLED战略发布会。会上,TCL实业副总裁TCL电子CEO张少勇先生发布会了TCL的MiniLED战略布局,力争在未来三好物有好价这三款手机屏幕都是顶级,售价却让人难以接受在购买商品时我们最常说的一句话便是一分钱一分货,好物有好价,大家都明白好的产品是建立在高昂成本上面的,这种规则无一例外。好物有好价的定律放到手机上也同样适用,虽然各家都在吹嘘性价比刷剧玩游戏这台电视能胜任所有客厅显示需求在后疫情时代,每当有假期来临,有人选择近郊旅行放松,有人热衷宅家刷剧玩游戏。中秋十一假期马上到来,俗话说工欲善其事必先利其器,宅家党们何不利用这个机会升级家中的电视,让假期看剧更爽如何清理爆满的C盘?教你4个方法,让你的电脑不再卡顿电脑在日常的生活中属于生活必须品,相信大家的家里都有一台,在使用电脑的过程中大家都会遇到一个问题C盘爆满了,导致电脑越来越卡!C盘爆满的主要原因如下下载的软件过多,没有及时清理和卸超高屏占比主打万物互联OPPO平板电脑曝光预装ColorOSForPad随着各大智能手机品牌自我生态建设的加速,多个品牌旗下的包括智能耳机智能手环智能手表智能电视智能音箱等Iot产品陆续发布或曝光。继realme真我手机的首款笔记本电脑发布之后,其传闻平板接口不够怎么办?扩展坞来解决,体验发现功能好多笔记本如今做得越来越薄,但也取消掉了许多东西,例如我们常用的HDMI接口以及USB3。0接口,这二种接口如今大多数笔记本上都找不到它们的身影,因为插口本身较大会影响笔记本厚度,取而性能超苹果!这手机我买定了手机圈一直都有一个说法,新款iPhone所搭载的芯片,基本就是地表最强,甭管是高通还是三星,都与苹果A系列有着不少差距。甚至还有人说,在同一时期内,它俩发布的手机芯片,也都落后于苹上市一年竟然不降价?麒麟芯片鸿蒙系统,荣耀X10依然真香众所周知手机市场竞争十分激烈,产品出现降价是很正常的事情,但物以稀为贵也是有道理的说法,在受到不公对待后,华为去年的一大批机型都开始缺货,甚至有涨价的情况,还波及到曾经的小弟荣耀,7nm麒麟芯片鸿蒙系统5G双模九频,跌至2299元8月初时华为鸿蒙系统官方宣布,HarmonyOS2升级用户已经突破5000万,现在过去接近20天了,升级用户量已经远不止这个数量了,为了满足用户的升级欲望,华为在之前的升级计划上,曾一机难求现有货还降价,鸿蒙OS麒麟9000,价格跌至新低一直以为,华为的口碑都非常不错,外观设计高端,系统非常流畅稳定,信号强等等,不过很少有人说其性价比高,因为华为并不是主打性价比的,跟小米等品牌相比,确实性价比不是优势,同档次的机型2000左右不要傻傻只知道红米了,五款平价手机推荐,高性价比有的人在买手机的时候,根本就不知道哪一款比较好,而是人云亦云地作出了选择,盲目跟风购买之后就会发现,原来这手机根本就不适合自己!有些人则是在网上寻找攻略积极了解,所以不要总是抱怨自
高考分数出来了,那么该配台电脑犒劳犒劳自己了(配置推荐)导读一天发两篇文章似乎不是我的风格,但是老程今晚上感觉自己文采斐然,甚至是感觉自己有点像当代文豪了,在键盘上挥洒青春,虽然家里很热,空调不管用,但是老程还是要给高考完的学生们弄个配打破规则奔腾B702。0T展现了一汽迈高求变的决心10月29日,一汽奔腾B702。0T车型正式上市。当人们议论,一汽奔腾在518战略下将以怎样的姿态进发之时,奔腾B702。0T车型给出了回应拔高产品定位,增强竞争力。时下,小排量发奔驰力挺普信男创始人杨笠车主像吃了苍蝇近来,自媒体和综艺节目的火热造就了一些颇具流量的网红。可能正是因为这些流量,车企们也开始通过网红来宣传品牌。但从日前的消息来看,这种宣传方式的成效似乎有些不尽人意,甚至还起到了反效刚交付就被55名车主联名维权极氪为何频繁翻车?如果在以前提起车主联合声明的字眼,相信大家都会第一时间想到惨遭黑天鹅事件的蔚来汽车。但就在前天,极氪001的数十名车主也被迫发起了联合声明,并且还做出了一张颇具设计感的车主发声海报前三季度紧凑型轿车投诉榜两车又被质疑黑心棉最近,汽车门网前三个季度的汽车投诉数据已经统计出来。前三季度紧凑型轿车整体投诉呈下降趋势,考虑到今年芯片短缺所导致的新车涨价缺货,所以新车投诉相比往年减少很多。接下来我们就来盘点一比亚迪2022款宋ProDMi四季度上市预售15万今年的中国车市,最亮眼的车企当属比亚迪,其凭借着DMi车型快速出圈,快省静顺绿五大核心优势深入人心,缔造了中国混动车型市场新格局。据悉,比亚迪四季度重磅车型2022款宋ProDMi八十岁的大爷也买影豹?探访影豹4S店入门级紧凑型轿车市场,一直是合资车企的地盘。日产轩逸丰田雷凌卡罗拉等车型的霸主地位几乎从未被动摇过。但随着消费者购车理念的变化,年轻人不再盲目追求品牌,自主品牌已经抓住机遇,在SU前三季度MPV投诉榜车机问题独占八成根据汽车门网前三个季度的汽车投诉数据显示,国内MPV的投诉指数总体呈下降趋势。其中,吉利嘉际的受到的投诉远远领先于其他MPV车型,大有一骑绝尘的趋势。其他车型的投诉量相互之间差距较运动与实用的完美融合试新奥迪A5Sportback颜值和实用往往并不共存,运动和家用也难两全其美,但是而这不是绝对。而能充分的将实用颜值运动和家用完美的融合在一起的就是最新一代的奥迪A5。它有着流线车身溜背造型高功率发动机的20210月SUV投诉指数排行变速箱和车机问题严重日前,汽车门网10月份汽车投诉指数出炉。10月份,汽车门网SUV车型的整体投诉指数为3178。3,环比9月份小幅上涨了5。22。TOP10榜单中,途观LRAV4荣放传祺GS4等车型老旧硬盘不要丢弃,教你怎么把老旧硬盘变废为宝导读可能很多小伙伴在升级的时候就会觉得旧的硬盘没啥用了,并且占地面积大,体积重扔在家里说不准就给小孩当做砖头打架用了,但是这样的旧硬盘卖的价格也不是很贵,现在翻新的500G机械盘的