实例详解javascript数组去重的几种思路

数据去重的需求实际上像是lodash这些工具库已经有成熟完备的实现,并且可以成熟地运用于生产环境。但是这并不妨碍我们从思维拓展的角度出发,看看去重可以用几种思路去实现。本文主要和大家分享javascript数组去重的几种思路。

首先是常规的双层循环比对的思路实现

function doubleLoopUniq(arr) {  let result = [];  for (let i = 0, len = arr.length, isExist; i < len; i++) {    // 定义一个变量表示当前元素在 result 中是否存在。    isExist = false;    for (let j = 0, rLen = result.length; j < rLen; j++) {      if (result[j] === arr[i]) {        // 依次对result 中的元素 和 原数组元素进行比对。        isExist = true;        break;      }    }    // 最后判断如果不存在,则将此元素插入result    !isExist && result.push(arr[i]);  }  return result;}

登录后复制

借助 js内置的indexOf 进行去重

function indexOfUniq(arr) {  let result = [];  for (let i = 0, len = arr.length; i < len; i++) {    // 用indexOf 简化了二层循环的流程    if (result.indexOf(arr[i]) === -1) result.push(arr[i]);  }  return result;}

登录后复制

排序后前后比对去重

function sortUniq(arr) {  let result = [], last;  // 这里解构是为了不对原数组产生副作用  [ ...arr ].sort().forEach(item => {    if (item != last) {      result.push(item);      last = item;    }  });  return result;}

登录后复制

通过hashTable去重

立即学习“Java免费学习笔记(深入)”;

function hashUniq(arr) {  let hashTable = arr.reduce((result, curr, index, array) => {    result[curr] = true;    return result;  }, {})  return Object.keys(hashTable).map(item => parseInt(item, 10));}

登录后复制

ES6 SET一行代码实现去重

function toSetUniq(arr) {  return Array.from(new Set(arr));}

登录后复制

splice 去重(直接操作数组本身,带副作用)

function inPlaceUniq(arr) {  let idx = 0;  while (idx < arr.length) {    let compare = idx + 1;    while (compare < arr.length) {      if (arr[idx] == arr[compare]) {        arr.splice(compare, 1);        continue;      }      ++compare    }    ++idx;  }  return arr;}

登录后复制

最后在nodejs下面简单跑个测试,看看哪个效率高~

let data = [];for (var i = 0; i < 100000; i++) {  data.push(Math.random())}// 实现一个性能测试的装饰器function performanceTest(fn, descript) {  var a = new Date().getTime();  return function () {    fn.apply(this, [].slice.call(arguments, 0));    console.log(descript, new Date().getTime() - a)  }}performanceTest(hashUniq, "hashTable")(data)performanceTest(sortUniq, "sortUniq")(data)performanceTest(toSetUniq, "toSetUniq")(data)performanceTest(indexOfUniq, "indexOfUniq")(data)performanceTest(doubleLoopUniq, "doubleLoopUniq")(data)performanceTest(inPlaceUniq, "inPlaceUniq")(data)

登录后复制

结果如下

hashTable 168mssortUniq 332mstoSetUniq 80msindexOfUniq 4280msdoubleLoopUniq 13303msinPlaceUniq 9977ms

登录后复制

延伸思考: 如果数组内的元素是对象该怎么去重呢?

既然是引用类型,那么不免会使用到deepEqual,固然这种思路可以解答这道问题,但难免不够高效。

从上面的测试中也可见通过new Set 和 hashTable 去重是最高效的。
所以毫无疑问,我们要基于这两种方式去改造,我想用的是hashTable,
另一方面,为了降低深度比较带来的耗时,我尝试用JSON.stringify 将引用类型转化为基本类型。

function collectionUniq(collection) {  let hashTable = {};  collection.forEach(item => {    hashTable[JSON.stringify(item)] = true;  })  return Object.keys(hashTable).map(item => JSON.parse(item))}

登录后复制

那么问题来了,我们都知道对象的属性是无序的,假如数据是这种情况,那就GG了。

let collection = [ { a: 1, b: 2, c: 3 }, { b: 2, c: 3, a: 1 } ]

登录后复制

有一种toHash的思路,在对这个数组进行一次基本的去重之后,为了保证准确,
先遍历JSON 字符串 =>
通过 charCodeAt()拿到每个字符串 的 unicode 编码 =>
相加得到一个总数,最后再两两进行比较,数值相等的就是重复的,这样就达到去重的效果了。

function toHash(obj) {  let power = 1;  let res = 0;  const string = JSON.stringify(obj, null, 2);  for (let i = 0, l = string.length; i < l; i++) {    switch (string[i]) {      case '{':        power *= 2        break      case '}':        power /= 2        break      case ' ':      case '':      case '':      case '':      break      default:        res += string[i].charCodeAt(0) * power    }  }  return res}

登录后复制

这只是一个实现基本的思路,有很大的改进空间,为了减少hash碰撞的可能,可以对一些特殊字符进行权重的增减。

重点是保证碰撞的几率小到比中大奖还小就可以了。

相关推荐:

JavaScript数组去重的几种方法分享

PHP实现数组去重的方法代码

JS简单实现数组去重的方法分析

以上就是实例详解javascript数组去重的几种思路的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2786865.html

(0)
上一篇 2025年3月8日 17:57:24
下一篇 2025年2月27日 07:30:55

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 前端框架ThinkJS框架详解

    本文主要和大家分享前端框架thinkjs框架详解,thinkjs 是一个快速、简单的基于mvc和面向对象的轻量级node.js开发框架,遵循mit协议发布。秉承简洁易用的设计原则,在保持出色的性能和至简的代码同时,注重开发体验和易用性,为w…

    编程技术 2025年3月8日
    200
  • 关于JavaScript面向对象的新认识

    1. javascript是一门面向对象的语言,在说明javascript是一个面向对象的语言之前, 我们来探讨一下面向对象的三大基本特征:  封装, 继承, 多态。本文我们就和大家重新介绍一下javascript面向对象。 封装 把抽象出…

    2025年3月8日
    200
  • JavaScript实现多叉树的递归遍历和非递归遍历算法操作示例

    这篇文章主要介绍了javascript实现多叉树的递归遍历和非递归遍历算法,结合实例形式详细分析了javascript多叉树针对json节点的递归与非递归遍历相关操作技巧,对javascript感兴趣的朋友可以参考下 本文实例讲述了Java…

    编程技术 2025年3月8日
    200
  • js中let和var如何定义变量

    js中let和var都可以定义变量,本文主要和大家介绍js中let和var定义变量的区别,非常不错,具有参考借鉴价值,需要的朋友可以参考下,希望能帮助到大家。 javascript 严格模式 第一次接触let关键字,有一个要非常非常要注意的…

    编程技术 2025年3月8日
    200
  • Nuxt.js Vue服务端渲染详解

    nuxt.js 十分简单易用。一个简单的项目只需将 nuxt 添加为依赖组件即可。本文主要和大家介绍了nuxt.js vue服务端渲染摸索,给大家做个参考,希望能帮助到大家。 Vue因其简单易懂的API、高效的数据绑定和灵活的组件系统,受到…

    编程技术 2025年3月8日
    200
  • JavaScript关于多叉树的递归遍历和非递归遍历算法分享

    本文主要和大家介绍了javascript实现多叉树的递归遍历和非递归遍历算法,结合实例形式详细分析了javascript多叉树针对json节点的递归与非递归遍历相关操作技巧,需要的朋友可以参考下,希望能帮助到大家。 演示之前的准备工作 演示…

    2025年3月8日
    200
  • 10种频率最高的Javascrip错误

    数据才是王道,我们收集并分析了出现频次排前 10 的 javascript 错误。 rollbar 会收集每个项目的所有错误,并总结每个错误发生的次数。我们通过根据 “指纹”(rollbar 用到的一种算法,详见:https://rollb…

    2025年3月8日 编程技术
    200
  • JavaScript实现简单放大镜效果代码

    本文主要和大家介绍了原生javascript实现的简单放大镜效果,涉及javascript事件响应及页面元素属性动态操作相关实现技巧,需要的朋友可以参考下,希望能帮助到大家。 原理: 其实所谓的放大就是准备两张一样的图片,除大小不一样。鼠标…

    2025年3月8日
    200
  • javascript中9个常见错误

    本文主要和大家介绍分析javascript中9 个常见错误阻碍你进步的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下,希望能帮助到大家。 分析javascript中9 个常见错误阻碍你进步 很多人尝试学习 JavaScript ,…

    编程技术 2025年3月8日
    200
  • 前端Javascript实现的机器学习类库实例

    web的整个体系已经在近几年中有了长足的发展, 虽然 javascript 和 node.js的使用案例还远远无法和java/python来媲美。 但是 也足够应用到很多机器学习的环境中去啦。而且最大的优势在于 – 一个浏览器就…

    2025年3月8日 编程技术
    200

发表回复

登录后才能评论