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 源码的第十八篇,后续文章会更新到 ...
随机推荐
- 【UML 建模】类图介绍
1.类图是面向对象系统建模中最常用和最重要的图,是定义其它图的基础.类图主要是用来显示系统中的类.接口以及它们之间的静态结构和关系的一种静态模型. 2.类的关系有泛化(Generalization). ...
- js中的undefined 和null
undefined是基本数据类型 表示未定义 缺少的意思 null是引用数据类型 是对象 表示空对象 undefined是从null派生出来的 所以undefined==null true Ja ...
- MongoDB用户权限管理
创建用户账号: (roles参数指定了用户的角色以及这个账号授权的数据库,在同一个数据库中不能同时创建两个用户名相同的账号) Mongodb内置的用户角色: 数据库用户角色:read.readWrit ...
- JavaScript+HTML5 实现打地鼠小游戏
一.游戏简介 打地鼠这个游戏相信大家都不陌生,也是童年时候一款经典的游戏.本次游戏的编写是以html文件形式完成的,并且使用HBulider软件进行编写,使用谷歌浏览器展示效果,游戏将会采用JavaS ...
- 高性能 Lua 技巧(译)
高性能 Lua 技巧(译) 来源 https://segmentfault.com/a/1190000004372649 此为 Lua Programming Gems 一书的第二章:Lua Perf ...
- Problem J
Problem Description 有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法? Input 输入数据首先包含一个整数N,表示测试实例的个数,然后是 ...
- KiKi's K-Number
KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- Rank of Tetris
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- 使用Lock锁生产者消费者模式
package com.java.concurrent; import java.util.concurrent.locks.Condition; import java.util.concurren ...
- font-size:100% 原因
The browser default which is something like 16pt for Firefox, You can check by going into Firefox op ...