lodash源码分析之chunk的尺与刀
以不正义开始的事情,必须用罪恶使它巩固。
——莎士比亚《麦克白》
最近很多事似乎印证了这句话,一句谎言最后要用一百句谎言来圆谎。
本文为读 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'
原理
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
存在和 size
比 1
大,如果不满足条件,返回空数组。
尺
在切割之前,需要用尺确定切割的数量。
从上面的原理分析可以看到,切割是不公平的,除了前面的块都是等分外,最后一块可能会比前面的少。
那怎么确定切割的数量呢?学过除法的知道, 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
相等时,表示已经切割完毕,停止切割,最后将结果返回。
参考
License
署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)
作者:对角另一面
我的博客即将同步至腾讯云+社区,邀请大家一同入驻。
lodash源码分析之chunk的尺与刀的更多相关文章
- lodash源码分析之自减的两种形式
这个世界需要一个特定的恶人,可以供人们指名道姓,千夫所指:"全都怪你". --村上春树<当我谈跑步时我谈些什么> 本文为读 lodash 源码的第六篇,后续文章会更新到 ...
- lodash源码分析之List缓存
昨日我沿着河岸/漫步到/芦苇弯腰喝水的地方 顺便请烟囱/在天空为我写一封长长的信 潦是潦草了些/而我的心意/则明亮亦如你窗前的烛光/稍有暧昧之处/势所难免/因为风的缘故 --洛夫<因为风的缘故& ...
- lodash源码分析之缓存方式的选择
每个人心里都有一团火,路过的人只看到烟. --<至爱梵高·星空之谜> 本文为读 lodash 源码的第八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitb ...
- lodash源码分析之缓存使用方式的进一步封装
在世界上所有的民族之中,支配着他们的喜怒选择的并不是天性,而是他们的观点. --卢梭<社会与契约论> 本文为读 lodash 源码的第九篇,后续文章会更新到这个仓库中,欢迎 star:po ...
- lodash源码分析之baseFindIndex中的运算符优先级
我悟出权力本来就是不讲理的--蟑螂就是海米:也悟出要造反,内心必须强大到足以承受任何后果才行. --北岛<城门开> 本文为读 lodash 源码的第十篇,后续文章会更新到这个仓库中,欢迎 ...
- lodash源码分析之数组的差集
外部世界那些破旧与贫困的样子,可以使我内心世界得到平衡. --卡尔维诺<烟云> 本文为读 lodash 源码的第十七篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodas ...
- lodash源码分析之compact中的遍历
小时候, 乡愁是一枚小小的邮票, 我在这头, 母亲在那头. 长大后,乡愁是一张窄窄的船票, 我在这头, 新娘在那头. 后来啊, 乡愁是一方矮矮的坟墓, 我在外头, 母亲在里头. 而现在, 乡愁是一湾浅 ...
- lodash源码分析之NaN不是NaN
暗恋之纯粹,在于不求结果,完全把自己锁闭在一个单向的关系里面. --梁文道<暗恋到偷窥> 本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-l ...
- lodash源码分析之获取数据类型
所有的悲伤,总会留下一丝欢乐的线索,所有的遗憾,总会留下一处完美的角落,我在冰峰的深海,寻找希望的缺口,却在惊醒时,瞥见绝美的阳光! --几米 本文为读 lodash 源码的第十八篇,后续文章会更新到 ...
随机推荐
- Linux.杀毒.Centos安装杀毒软件Clam
Linux系统用了几年, 甚少中毒 但前不久在阿里云的服务器被种马,折腾了几周才解决干净 感觉还是装个杀毒/马软件定期扫一扫比较稳妥, 这个Clam是免费的, 安装和配置办法记录如下: 已验证适用环境 ...
- url 地址处理(截取,参数等)
function hrefObj() { var localhref = window.location.href; var localarr = localhref.split('?')[1].sp ...
- TreeView简单的动态加载数据
简单的小记录,省得去看控件属性详情了,基本常用的属于就几个 先是判断根节点是否存在控件中,如果不存在则创建,之前要添加了节点同样的方法 把根节点传到子节点的方法中,再判断是否在根节点里存在子节点,如果 ...
- webpack学习(一)
1.首先建立一个webpack项目,然后新建文件demo2,在demo2下新建src文件,index.html文件,初始化项目 (npm init --yes)得到package.json 2.全局安 ...
- B. An express train to reveries
B. An express train to reveries time limit per test 1 second memory limit per test 256 megabytes inp ...
- windows 上rsync客户端使用方法
1.1 获取 windows上实现rsync的软件(cwRsync) cwRsync是Windows 客户端GUI的一个包含Rsync的包装.您可以使用cwRsync快速远程文件备份和同步. 1.1. ...
- javascript 之变量对象-09
变量对象 变量对象:每个执行环境(执行上下文)都有一个对应的变量对象(variable object),环境中(执行上下文中)定义的所有变量.函数都保存在这个对象中. 在上篇中说到,当执行流执行一个函 ...
- 0_Simple__cppIntegration
引用已经编好的 .cu 和 .cpp 代码来混合使用.在 main.cpp 中调用了使用GPU的 cppIntegration.cu (测试函数也在其中) 和使用CPU的 cppIntegration ...
- Cocoapods安装过程
1.升级Ruby环境 gem -v gem update --system 如果没有权限去升级Ruby ?就输入 sudo gem update --system 2.换掉Ruby镜像 首先移除现有的 ...
- javaWeb内置对象
jsp内置对象是web容器创建的一组对象. jsp内置对象的名称是jsp的保留字. jsp内置对象是可以直接在jsp页面使用的对象,无需使用new获取实例. jsp九大内置对象 1.request 2 ...