以不正义开始的事情,必须用罪恶使它巩固。

——莎士比亚《麦克白》

最近很多事似乎印证了这句话,一句谎言最后要用一百句谎言来圆谎。

本文为读 lodash 源码的第二篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash

gitbook也会同步仓库的更新,gitbook地址:pocket-lodash

作用与用法

chunk 函数可以将一个数组,切割成指定大小的块,返回由这些块组成的新数组。

chunk 函数在前端可以用来缓解一些性能问题。例如大量的 DOM 操作,可以分块让浏览器在空闲的时候处理,避免页面卡死。如下面的代码,向页面中插入大量的DOM。

const arr = [] // 1万条数据
const chunks = _.chunk(arr, 100) const append = function () {
if (chunks.length > 0) {
const current = chunks.pop()
current.forEach(item => {
const node = document.createElement('div')
node.innerText = item
document.body.appendChild(node)
})
setTimeout(append, 0)
}
} append()

依赖

import slice from './slice.js'

读lodash源码之从slice看稀疏数组与密集数组

原理

chunk 的原理归结起来就是切割和放置。

chunk 最后返回的结果如 [[1],[1],[1]] 的形式,放置就是将切割下来的块放置到数组容器中。

那要怎样切割呢?

因为指定了大小,因此切割跟切蛋糕很像,参数 size 是尺子,测好每块的长度,slice 函数是刀, 将数组一块一块切出来。

例如有 [1,2,3,4,5] 这个数组,size 指定为 2,则第一次切割会得到 [1,2] 的块,第二次切割得到 [4,5],剩下的是 [5] 。这个数组最终会被切为三块。

明白了原理,下面来看看源码。

源码总览

function chunk(array, size) {
size = Math.max(size, 0)
const length = array == null ? 0 : array.length
if (!length || size < 1) {
return []
}
let index = 0
let resIndex = 0
const result = new Array(Math.ceil(length / size)) while (index < length) {
result[resIndex++] = slice(array, index, (index += size))
}
return result
}

参数处理

size = Math.max(size, 0)
const length = array == null ? 0 : array.length
if (!length || size < 1) {
return []
}

确保 length 存在和 size1 大,如果不满足条件,返回空数组。

在切割之前,需要用尺确定切割的数量。

从上面的原理分析可以看到,切割是不公平的,除了前面的块都是等分外,最后一块可能会比前面的少。

那怎么确定切割的数量呢?学过除法的知道, length/size 即可知道平均分块的数量,如果有余数,则余数是最后那块的长度,需要向上取整。

这在 javascript 中可以用 Math.ceil 函数,它返回的是向上取整后的结果。

看下代码:

const result = new Array(Math.ceil(length / size))

这里创建了一个用来放置所有块的容器 result 。容器的长度刚好与块的数量一致。

let index = 0
let resIndex = 0
while (index < length) {
result[resIndex++] = slice(array, index, (index += size))
}

测量好块的数量后,就要下刀切割啦。每切割下一块,就立马放置到容器 result 中。

resIndex 是放置块的位置,index 是切割的开始位置。

index 与块的数量 length 相等时,表示已经切割完毕,停止切割,最后将结果返回。

参考

  1. lodash源码解析——chunk函数

License

署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)

作者:对角另一面

我的博客即将同步至腾讯云+社区,邀请大家一同入驻。

lodash源码分析之chunk的尺与刀的更多相关文章

  1. lodash源码分析之自减的两种形式

    这个世界需要一个特定的恶人,可以供人们指名道姓,千夫所指:"全都怪你". --村上春树<当我谈跑步时我谈些什么> 本文为读 lodash 源码的第六篇,后续文章会更新到 ...

  2. lodash源码分析之List缓存

    昨日我沿着河岸/漫步到/芦苇弯腰喝水的地方 顺便请烟囱/在天空为我写一封长长的信 潦是潦草了些/而我的心意/则明亮亦如你窗前的烛光/稍有暧昧之处/势所难免/因为风的缘故 --洛夫<因为风的缘故& ...

  3. lodash源码分析之缓存方式的选择

    每个人心里都有一团火,路过的人只看到烟. --<至爱梵高·星空之谜> 本文为读 lodash 源码的第八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitb ...

  4. lodash源码分析之缓存使用方式的进一步封装

    在世界上所有的民族之中,支配着他们的喜怒选择的并不是天性,而是他们的观点. --卢梭<社会与契约论> 本文为读 lodash 源码的第九篇,后续文章会更新到这个仓库中,欢迎 star:po ...

  5. lodash源码分析之baseFindIndex中的运算符优先级

    我悟出权力本来就是不讲理的--蟑螂就是海米:也悟出要造反,内心必须强大到足以承受任何后果才行. --北岛<城门开> 本文为读 lodash 源码的第十篇,后续文章会更新到这个仓库中,欢迎 ...

  6. lodash源码分析之数组的差集

    外部世界那些破旧与贫困的样子,可以使我内心世界得到平衡. --卡尔维诺<烟云> 本文为读 lodash 源码的第十七篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodas ...

  7. lodash源码分析之compact中的遍历

    小时候, 乡愁是一枚小小的邮票, 我在这头, 母亲在那头. 长大后,乡愁是一张窄窄的船票, 我在这头, 新娘在那头. 后来啊, 乡愁是一方矮矮的坟墓, 我在外头, 母亲在里头. 而现在, 乡愁是一湾浅 ...

  8. lodash源码分析之NaN不是NaN

    暗恋之纯粹,在于不求结果,完全把自己锁闭在一个单向的关系里面. --梁文道<暗恋到偷窥> 本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-l ...

  9. lodash源码分析之获取数据类型

    所有的悲伤,总会留下一丝欢乐的线索,所有的遗憾,总会留下一处完美的角落,我在冰峰的深海,寻找希望的缺口,却在惊醒时,瞥见绝美的阳光! --几米 本文为读 lodash 源码的第十八篇,后续文章会更新到 ...

随机推荐

  1. C 其他一些

    1.联合,语法 union{成员1;成员2;} 联合间的成员共享同一个空间,也就是说,成员1赋值如果没有被清除,会体现在成员2上 2.位字段,结合结构体瓜分完整的类型存储空间,如 struct{ ; ...

  2. Tomcat 笔记-配置虚拟目录

    ,默认情况下,只有webapps下的目录才能被Tomcat自动管理成一个web站点,把web站点的目录分散到其他磁盘管理就需要配置虚拟目录.把web应用所在目录交给web服务器管理,这个过程称之为虚拟 ...

  3. Maven 结合 IDEA 入门实践

    一.Maven 基本安装 1. 下载 首先来到 http://maven.apache.org/download.cgi ,直接下载以 -bin.zip 结尾的文件,如图 2. 存储位置 将其解压后, ...

  4. JS模拟实现封装的三种方法

      前  言  继承是使用一个子类继承另一个父类,那么子类可以自动拥有父类中的所有属性和方法,这个过程叫做继承!  JS中有很多实现继承的方法,今天我给大家介绍其中的三种吧. 1.在 Object类上 ...

  5. Linux中main是如何执行的

    Linux中main是如何执行的 这是一个看似简单的问题,但是要从Linux底层一点点研究问题比较多.找到了一遍研究这个问题的文章,但可能比较老了,还是在x86机器上进行的测试. 原文链接 开始 问题 ...

  6. 4本相见恨晚的Linux入门书籍

    有读者问可否推荐一些 Linux 入门书籍,刚好在知乎也看到类似的问题,几个零碎的命令难以在 Linux 环境中存活,如果要真正形成自己的知识体系,还是要靠阅读专业书籍来积累.Linux 对后端开发是 ...

  7. Oracle结合Mybatis实现取表中前10条数据

    之前一直使用mysql和informix数据库,查表中前10条数据十分简单: 最原始版本: select top * from student 当然,我们还可以写的复杂一点,比如外加一些查询条件? 比 ...

  8. Javascript数组求和的方法总结 以及由斐波那契数列得到的启发

    一次面试中,面试官要求用三种不同的Javascript方法进行一个数字数组的求和,当时思来想去只想到了使用循环这一种笨方法,因此面试比较失败,在这里总结了六种Javascript进行数组求和的方法,以 ...

  9. 通讯框架 T-io 学习——给初学者的Demo:ShowCase设计分析

    前言 最近闲暇时间研究Springboot,正好需要用到即时通讯部分了,虽然springboot 有websocket,但是我还是看中了 t-io框架.看了部分源代码和示例,先把helloworld敲 ...

  10. Promise同时进入catch和then——踩坑

    记录今天使用Promise遇到的一个坑--在resolve()返回运行then之后,函数又进入到了catch,源代码大意如下: var pro = function() { return new Pr ...