Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >lodash源码阅读-----由zip和unzip实现的数组的分组合并

lodash源码阅读-----由zip和unzip实现的数组的分组合并

作者头像
Jou
发布于 2022-08-10 12:40:59
发布于 2022-08-10 12:40:59
52200
代码可运行
举报
文章被收录于专栏:前端技术归纳前端技术归纳
运行总次数:0
代码可运行

用法

zip方法接收传入多个数组,它会创建分组元素的数组,第一个数组包含给定数组的第一个元素,第二个元素包含给定数组的第二个元素,依此类推,最后返回这个数组。

unzip方法和zip方法的用法近似相反,只是它接受一个分组数组元素并创建一个数组,将元素重新组合到它们的预压缩配置。

来看看用法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 const zipped = zip(['a', 'b'], [1, 2], [true, false])
 // => [['a', 1, true], ['b', 2, false]]
 
 unzip(zipped)
 // => [['a', 'b'], [1, 2], [true, false]]

解析

我们先看zip方法的源码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function zip(...arrays) {
  return unzip(arrays)
}

由于zip方法是通过调用unzip方法实现的,所以我们直接来看unzip方法的实现。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function unzip(array) {
  if (!(array != null && array.length)) {
    return []
  }
  let length = 0
  array = filter(array, (group) => {
    if (isArrayLikeObject(group)) {
      length = Math.max(group.length, length)
      return true
    }
  })
  let index = -1
  const result = new Array(length)
  while (++index < length) {
    result[index] = map(array, baseProperty(index))
  }
  return result
}

函数首先对数组进行了检测,以此确保数组有意义,之后进一步做了循环,来看看这个循环。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 let length = 0
  array = filter(array, (group) => {
    if (isArrayLikeObject(group)) {
      length = Math.max(group.length, length)
      return true
    }
  })

该循环使用isArrayLikeObject方法对数组中的每个目标数组进行了检测,确保其有意义,并且将length赋值为子数组的最大长度,以此确定合并后的数组长度。

之后看看isArrayLikeObject方法,这个方法做了两步检测

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function isArrayLikeObject(value) {
  return isObjectLike(value) &amp;&amp; isArrayLike(value)
}

function isArrayLike(value) {
  return value != null &amp;&amp; typeof value !== 'function' &amp;&amp; isLength(value.length)
}

function isObjectLike(value) {
  return typeof value === 'object' &amp;&amp; value !== null
}
  • isArrayLike方法,除了检测value不为空和function外,还检测它是否具有length属性,目的是筛选出不为数组,但是具有length属性的元素,如string,document.body.children
  • isObjectLike方法进一步检测了value必须是一个不为null的对象

所以这里排除了string,value只能为数组,document.body.children,或arguments等类数组。

看完接着看函数后面的代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let index = -1
  const result = new Array(length)
  while (++index < length) {
    result[index] = map(array, baseProperty(index))
  }
  return result

这里有两个遍历,while循环的循环长度是,子数组的最大长度,然后在循环内部,再将子数组相同位置的元素放如合并数组。这里map的传入函数是baseProperty,来看看它的实现。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function baseProperty(key) {
  return (object) => object == null ? undefined : object[key]
}

这里返回了一个函数,置入map的话就是这样的,目的是为了去掉长度不对等的子数组中的空元素。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
result[index] = map(array, item => {
    item == null ? underfined : object[index]
})

总结

zip和unzip方法可以实现数组的分组和合并,源码实现并不难,还是主要通过两层的遍历实现的,但是考虑了很多的边界条件。

想到了一个使用场景:假如现在有一个数组存了每个学生的年龄,一个数组存了每个学生的姓名,现在需要拆分成单个的学生对象,那就可以用unzip来进行分组,之后再转化为对象,就不用多次的遍历。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
HashMap源码阅读
HashMap是Map家族中使用频度最高的一个,下文主要结合源码来讲解HashMap的工作原理。 1. 数据结构 HashMap的数据结构主要由数组+链表+红黑树(JDK1.8后新增)组成,如下图所示: 左侧数组是哈希表,数组的每个元素都是一个单链表的头节点,当不同的key映射到数组的同一位置,就将其放入单链表中来解决key的hash值的冲突。 当链表的长度>8时,JDK1.8做了数据结构的优化,会将链表转化为红黑树,利用红黑树快速增删改查的特点提升HashMap的性能,查询效率链表O(N),红黑树是O(l
butterfly100
2018/04/17
7100
HashMap源码阅读
这些Zepto中实用的方法集
根据文章内容撰写摘要总结。
IMWeb前端团队
2017/12/29
8430
这些Zepto中实用的方法集
JavaScript中的类型判断
类型判断在 web 开发中有非常广泛的应用,简单的有判断数字还是字符串,进阶一点的有判断数组还是对象,再进阶一点的有判断日期、正则、错误类型,再再进阶一点还有比如判断 plainObject、空对象、Window 对象等等。
ConardLi
2019/05/23
1.3K0
内功修炼之lodash——chunk、zip、groupBy、invokeMap方法
本文实现方法都是看效果倒推实现方法,并进行一些拓展和思考,和源码无关。lodash这个库在这里更像一个题库,给我们刷题的
lhyt
2019/10/28
1.3K0
lodash源码阅读-----用于过滤的方法pull
lodash还有一个pullAll方法,用法几乎都是一样的,不同的只是它接收两个参数,第一个是目标数组,第二参数也是一个需要除去元素构成的数组。
Jou
2022/08/10
6320
Python中的zip/unzip:像拉拉链一样组合数据的艺术
今天让我们一起探讨Python中一个优雅而强大的内置功能: zip 和 unzip 。听名字就知道,它就像我们衣服上的拉链一样,能把两边的数据完美地咬合在一起。
Piper破壳
2024/12/19
1370
lodash源码阅读-----从简单的split开始
首先,对传入的limit进行了校验,如果没有传,那么就把分解的字符全部保留下来,如果传了,那么使用 使limit进行有意义的转化(如非负,不能有小数),如果limit没有意义则返回空数组
Jou
2022/08/10
5400
【Html.js——函数编写】分一分(蓝桥杯真题-2438)【合集】
请在 js/index.js 文件中补全函数 splitArray 中的代码,最终返回按指定长度分割的数组。
Rossy Yan
2025/03/06
430
【Html.js——函数编写】分一分(蓝桥杯真题-2438)【合集】
大厂面试:JavaScript各种源码解析
func 是要调用的函数,是由 context 调用,func 的指向 context,所以关注点在 context 指向
Javanx
2019/09/04
7280
JavaScript权威指南 - 数组
JavaScript数组是一种特殊类型的对象。 JavaScript数组元素可以为任意类型,最大容纳232-1个元素。 JavaScript数组是动态的,有新元素添加时,自动更新length属性。 JavaScript数组元素索引可以是不连续的,它们之间可以有空缺。
Esofar
2018/09/05
4.2K0
HashMap源码阅读笔记
HashMap采用 key/value 存储结构,每个key对应唯一的value。
三分恶
2020/11/03
4900
jQuery源码研究:为jQ对象扩展的一些工具方法(下)
解释:如果参数text值为null或者undefined,则返回空字符串;否则就通过replace()方法传入对应正则进行匹配替换。这里rtrim参数变量是在源码开头就定义好的的一个正则表达式变量rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;。
前端_AWhile
2019/08/29
8910
06_JavaScript数组
保存一个班级学生信息,每个数组元素都代表一个学生,而每个学生都使用一个一维数组分别表示其姓名、学号、年龄等信息,这样通过一个变量即可有规律的保存一个班级的所有学生信息,方便开发时进行处理。
用户9184480
2024/12/13
1260
JS算法探险之数组
大家好,我是柒八九。这篇文章是我们算法探险系列的第三篇文章。是针对数据结构方面的第二篇。上一篇JS算法探险之整数中我们介绍了关于JS整数的一些基础知识和相关算法题。我们做一个简单的「前情回顾」。
前端柒八九
2022/08/25
8600
JS算法探险之数组
ioredis源码阅读[0]
从项目中看,源码都在 lib 文件夹下,是一个纯粹的 TS 项目。 lib 目录下的文件主要是一些通用能力的提供,比如 command、pipeline以及数据的传输等。
贾顺名
2020/12/18
5890
ioredis源码阅读[0]
Java工具集-数组(ArrayUtil)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
cwl_java
2019/10/28
1.3K0
高频js手写题之实现数组扁平化、深拷贝、总线模式
古人学问无遗力,少壮工夫老始成。纸上得来终觉浅,绝知此事要躬行。看懂一道算法题很快,但我们必须将这道题的思路理清、手写出来。
helloworld1024
2022/10/06
3770
lodash源码分析之compact中的遍历
本文为读 lodash 源码的第三篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
对角另一面
2018/01/17
8430
从underscore源码看如何实现map函数
经常会看到这样的面试题,让面试者手动实现一个 map 函数之类的,嗯,貌似并没有什么实际意义。但是对于知识探索的步伐不能停止,现在就来分析下如何实现 map 函数。
桃翁
2018/12/25
8990
【JDK1.8】JDK1.8集合源码阅读——ArrayList
一、前言 在前面几篇,我们已经学习了常见了Map,下面开始阅读实现Collection接口的常见的实现类。在有了之前源码的铺垫之后,我们后面的阅读之路将会变得简单很多,因为很多Collection的结
joemsu
2018/05/17
8640
相关推荐
HashMap源码阅读
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验