虽然算法在前端开发中很少会得以使用,但是了解常用的算法,熟悉各种算法的性能和优劣,将会让你在前端的道路上走的更远。

前言

文中所有代码位于位于此代码仓库中,大家可以下载代码进行学习、推敲和改进。另,如果觉得这些用心推敲的代码对你有帮助的话,欢迎 star 一下代码仓库,众筹博主的小星星。

另外,本文中使用如下函数对代码进行性能测试:

module.exports = async function getFnRunTime(fn) {let startTime = Date.now(), endTime;let result = await fn();endTime = Date.now();console.log(`total time:${endTime-startTime}ms`,'test array'length:' + len, result.length);
}

为了衡量性能,我们引入代码时间复杂度的概念,用大写O()来表现算法时间复杂度的记法,我们称之为大O记法。一般情况下,随着n的增大,T(n)增长最慢的算法为最优算法。

1.双重for循环去重

如果有相同的值则跳过,不相同则push进数组

function distinct1(arr = testArr) {let result = [],len = arr && arr.length;for (let i=0; i< len; i++) {for (let j=i+1; j< len; j++) {if (arr[i] === arr[j]) {j = ++i;}}result.push(arr[i])}return result
}

由于使用了双层for循环,根据代码可知时间复杂度为O(n^2),用测试函数测的19815条数据的去重时间为:7-8ms;

2.利用indexOf和forEach/for循环去重

function distinct2(arr = testArr) {let result = [];arr.forEach((v, i, array) => {array.indexOf(v, i+1) === -1 && result.push(v)});return result
}

可以看到该方法的代码很简洁,时间复杂度为O(n),但是indexOf会进行额外的性能消耗,测试相同的数据耗时为:4-5ms

3.对象法

通过利用对象建名的唯一性去去重

function distinct3(arr = testArr) {let result = [], resultObj = {}, len = arr.length;for(let i=0; i< len; i++) {let val = arr[i],type = typeof val;if(!resultObj[val]) {result.push(val);resultObj[val] = [type];} else if(!resultObj[val].indexOf(type) < 0) {result.push(val);resultObj[val] = [type];}}return result
}

该方法很快,时间复杂度为O(n),但是由于会多创建一个对象,会带来额外的内存开销,尤其是数据量大的情景下,测试相同的数据耗时为:5ms

4.filter去重方法一

利用filter和indexOf来查询

function distinct4(arr = testArr) {return arr.filter((v, i, array) => array.indexOf(v, i+1) < 0)
}

该方法也很简洁,测试相同的数据耗时为:4-5ms,关键优化点是利用indexOf的第二个参数去避免不必要的查询。

5.filter去重方法二

和方法4的区别是利用数组的索引的唯一性来去重

function distinct5(arr = testArr) {return arr.filter((v, i, array) => array.indexOf(v) === i)
}

该方法同4,但是性能远不如方法4,因为数组每次调用indexOf都会重新查找整个数组,但这是必须要做的操作,否则就不能利用数组索引的唯一性了。耗时:16ms(小伙伴们都惊呆了)

6.利用es6的set方法

function distinct6(arr = testArr) {return [...new Set(arr)]
}

此方法耗时1ms,但是局限性很大,针对相同类型的数据很快,但是不同类型的数据去重,将非常慢,这涉及到js相关的底层知识,这里就先不介绍了,后期需要的话可以专门上一篇文章介绍~

好啦,其实数组去重有很多种方法,只有你想不到的,没有实现不了的,如果你有更好更快的方法,欢迎一起交流探讨哦~

去重查询_《前端算法系列》数组去重相关推荐

  1. java算法判断链表有没有闭环_前端算法系列之二:数据结构链表、双向链表、闭环链表、有序链表...

    前言 上一次我们讲到了数据结构:栈和队列,并对他们的运用做了一些介绍和案例实践:我们也讲到了怎么简单的实现一个四则运算.怎么去判断标签是否闭合完全等等,anyway,今天接着和大家介绍一些数据结构: ...

  2. es6 数组去重_《前端算法系列》数组去重

    虽然算法在前端开发中很少会得以使用,但是了解常用的算法,熟悉各种算法的性能和优劣,将会让你在前端的道路上走的更远. 前言 文中所有代码位于位于此代码仓库中,大家可以下载代码进行学习.推敲和改进.另,如 ...

  3. java数组去重_再谈JavaScript数组去重

    JavaScript的数组去重是一个老生常谈的话题了.随便搜一搜就能找到非常多不同版本的解法. 细想一下,这样一个看似简单的需求,如果要做到完备,涉及的知识和需要注意的地方着实不少. 定义重复(相等) ...

  4. gif透明背景动画_前端基础系列之bmp、jpg、png、gif、svg常用图片格式浅谈(二)...

    IT客栈 作者:大腰子 bmp.jpg.png.gif.svg常用图片格式 之前为大家介绍了几种WEB前端常用的图片格式,对比了它们的特点,参见<前端基础系列之bmp.jpg.png.gif.s ...

  5. 重复次数最多的 子串_每日算法系列【LeetCode 424】替换后的最长重复字符

    题目描述 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 示例1 输入: s = &quo ...

  6. 数组去重 php,PHP编程快速实现数组去重的方法详解

    本文实例讲述了PHP编程快速实现数组去重的方法.分享给大家供大家参考,具体如下: 概述 使用PHP的array_unique()函数允许你传递一个数组,然后移除重复的值,返回一个拥有唯一值的数组.这个 ...

  7. [饭后算法系列] 数组中和非负的最长子数组

    1. 问题 给定一列数字数组 a[n], 求这个数组中最长的 "和>=0" 的子数组. (注: "子数组"表示下标必须是连续的. 另一个概念"子 ...

  8. indexof方法_[ 翻译 ] ES6中数组去重的三种方法

    原文:How to Remove Array Duplicates in ES6 翻译:Hytonight云息 有三种方法可以过滤掉一个数组的重复元素并且返回去重后的新数组.我最喜欢使用Set,因为它 ...

  9. 数组最大可以开多大_每日算法系列【LeetCode 689】三个无重叠子数组的最大和

    题目描述 给定数组 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为 ,我们要使这 个项的和最大化. 返回每个区间起始索引的列表(索引从 0 开始).如果有多个结果,返回字典序最小 ...

最新文章

  1. 前端共享桌面_2020 前端学习路线总结,哎呦,不错哦!
  2. 高通量数据中批次效应的鉴定和处理(六)- 直接校正表达矩阵
  3. php的mbstring模块安装折腾记录
  4. 小米笔试题:无序数组中最小的k个数
  5. world wide web publishing无法启动 127错误
  6. 笔记本 WIFI 热点批处理文件
  7. 面完18家大厂的算法岗位,吐血整理了一个面经!
  8. cesium--entity
  9. Android开发如何定制framework层服务
  10. oracle 存储过程中使用select 列 into 变量
  11. Android错误提示及解决方案(持续更新)
  12. Joost大行其道 P2P网络电视颠覆传统电视工业?
  13. JavaScript内置对象Ⅰ
  14. Keil软件仿真步骤
  15. SQL Server2000挂起 cd-key
  16. Go 和 Golang 有什么关系?
  17. LCD显示器参数详解
  18. 下载spotify音乐_完成播放列表或专辑后如何停止Spotify停止自动播放音乐
  19. Java开发实例大全提高篇——XML篇
  20. Linux作为哑终端连接服务器,linux – TERM =哑终端必须具备的功能

热门文章

  1. 再见了Redis!这个数据库有点厉害,甚至碾压了Oracle!
  2. 从入职快手3年股票3000w说起
  3. 关于MySQL线程池,这也许是目前最全面的实用帖!
  4. 一次 HashSet 所引起的并发问题
  5. 微信如何实施微服务?
  6. 电子商务网站是这样诞生的
  7. 开源项目管理软件,团队协作配合新方式
  8. OKR落地,实践经验总结两个点比较重要
  9. 简单粗暴彻底解决selenium+chromedriver无法定位各种元素的方法
  10. Ubuntu系统安装搜狗输入法详细教程