阅读lodash源码之旅数组方法篇-compact和concat
鲁迅说过:只有阅读过优秀库源码的人,才能配的上是真正的勇士。
compact
创建一个新数组,包含原数组中所有的非假值元素。例如false, null,0, “”, undefined, 和 NaN 都是被认为是“假值”。
注意以上的描述并不包括[],{}因为在js中,这个两个会进行隐式转换会把这两个值转换成为true。换句话来说该函数并不会去过滤这两个值。
官方代码:
export function compact(array){
let resIndex = 0;
const result = []
if(array == null){ // 会把undefined给排除掉 因为 undefined == null 为true
return result
}
for(const value of array){
if(value){
result[resIndex++] = value
}
}
return result
}
个人理解代码:
export function compact(array){
let resIndex = 0;
const result = []
if(array == null){ // 会把undefined给排除掉 因为 undefined == null 为true
return result
}
result = array.filter(v=>Boolean(v))
return result
}
直接利用filter进行遍历,利用boolean,来对元素进行真假转换。
concat
创建一个新数组,将array与任何数组 或 值连接在一起。
var array = [1];
var other = _.concat(array, 2, [3], [[4]]);
console.log(other);
// => [1, 2, 3, [4]]
console.log(array);
// => [1]
相对来说,concat函数所依赖的工具函数就多几个。
- arrayPush数组添加方法
- copyArray拷贝数组元素
- baseFlatten扁平层级数组
export function concat(){
let length = arguments.length; // 获取参数的个数
if (!length) {
return [];
}
let args = Array(length - 1); // 取除了第一个参数以外的参数的长度
let array = arguments[0]; // 取出数组的第一项
let index = length;
while (index--) {
args[index - 1] = arguments[index];
}
console.log(args); // 把第一个参数也就是目标数组,当作-1项添加为array
// 判断一个参数是否是数组,不是就把它转换成为数组,如果是数组则拷贝一份数组,再使用arrayPush方法,把每项的参数推进数组里面去。
return arrayPush(Array.isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
}
copyArray
拷贝数组,此操作不会影响到原有的数组。
参数 | 说明 |
---|---|
soure | 原数组参数 |
array | 结果数组 |
export function copyArray(source,array){
let index = -1;
let length = source.length;
array || (array = Array(length));
while(++index < length){
array[index] = source[index]
}
return array
}
baseFlatten
该方法主要用于扁平数组的操作
export function baseFlatten(array, depth, predicate, isStrict, result) {
let index = -1;
let length = array.length;
predicate || (predicate = isFlattenable); // isFlattenable 判断是否是数组
result || (result = []);
while (++index < length) {
let value = array[index];
console.log(value);
if (depth > 0 && predicate(value)) { // 如果层级大于0并且该项是数组的话
if (depth > 1) { // 如果需要递归的层级大于1的情况则继续递归下去解套
baseFlatten(value, depth - 1, predicate, isStrict, result);
} else { // 如果需要递归的层级为1的情况,则把所有的项添加目标数组
arrayPush(result, value);
}
} else if (!isStrict) {
result[result.length] = value;
}
}
return result;
}
isFlattenable(value){
return Array.isArray(value)
}
发散思考,该函数只要是通过depth变量,来控制筛选的层级,那么我希望实现扁平所有的数组,那应该怎么操作呢?
function flattern(arr) {
return arr.reduce((cur, next) => cur.concat(Array.isArray(next) ? flattern(next) : next), []);
}
arrayPush
添加元素进入原数组,会改变原数组结构,类似push方法
let index = -1;
let length = values.length;
let offset = array.length;
while (++index < length) {
array[index + offset] = values[index];
}
return array;
总结
- ++index和index++不同之处,++i就是先加后用,i++就是先用后加。前置++下标不会越界,后置++下标越界。
- lodash库操作数组一般都不会影响原有数组。
阅读lodash源码之旅数组方法篇-compact和concat的更多相关文章
- 手把手带你阅读Mybatis源码(三)缓存篇
前言 大家好,这一篇文章是MyBatis系列的最后一篇文章,前面两篇文章:手把手带你阅读Mybatis源码(一)构造篇 和 手把手带你阅读Mybatis源码(二)执行篇,主要说明了MyBatis是如何 ...
- lodash源码分析之数组的差集
外部世界那些破旧与贫困的样子,可以使我内心世界得到平衡. --卡尔维诺<烟云> 本文为读 lodash 源码的第十七篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodas ...
- 手把手带你阅读Mybatis源码(一)构造篇
前言 今天会给大家分享我们常用的持久层框架——MyBatis的工作原理和源码解析,后续会围绕Mybatis框架做一些比较深入的讲解,之后这部分内容会归置到公众号菜单栏:连载中…-框架分析中,欢迎探讨! ...
- 手把手带你阅读Mybatis源码(二)执行篇
前言 上一篇文章提到了MyBatis是如何构建配置类的,也说了MyBatis在运行过程中主要分为两个阶段,第一是构建,第二就是执行,所以这篇文章会带大家来了解一下MyBatis是如何从构建完毕,到执行 ...
- 从源码角度看finish()方法的执行流程
1. finish()方法概览 首先我们来看一下finish方法的无参版本的定义: /** * Call this when your activity is done and should be c ...
- lodash源码分析之获取数据类型
所有的悲伤,总会留下一丝欢乐的线索,所有的遗憾,总会留下一处完美的角落,我在冰峰的深海,寻找希望的缺口,却在惊醒时,瞥见绝美的阳光! --几米 本文为读 lodash 源码的第十八篇,后续文章会更新到 ...
- 读lodash源码之从slice看稀疏数组与密集数组
卑鄙是卑鄙者的通行证,高尚是高尚者的墓志铭. --北岛<回答> 看北岛就是从这两句诗开始的,高尚者已死,只剩卑鄙者在世间横行. 本文为读 lodash 源码的第一篇,后续文章会更新到这个仓 ...
- lodash源码分析之compact中的遍历
小时候, 乡愁是一枚小小的邮票, 我在这头, 母亲在那头. 长大后,乡愁是一张窄窄的船票, 我在这头, 新娘在那头. 后来啊, 乡愁是一方矮矮的坟墓, 我在外头, 母亲在里头. 而现在, 乡愁是一湾浅 ...
- lodash源码分析之Hash缓存
在那小小的梦的暖阁,我为你收藏起整个季节的烟雨. --洛夫<灵河> 本文为读 lodash 源码的第四篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbo ...
随机推荐
- react第四单元(ref与DOM-findDomNode-unmountComponentAtNode)
第四单元(ref与DOM-findDomNode-unmountComponentAtNode) #课程目标 理解react的框架使用中,真实dom存在的意义. 使用真实dom和使用虚拟dom的场景. ...
- WebSocket实现站内消息实时推送
关于WebSocket WebSocket是HTML5 开始提供的一种在单个TCP连接上进行全双工通讯的协议.什么是全双工?就是在同一时间可以发送和接收消息,实现双向通信,比如打电话.WebSocke ...
- phpstorm ext-json is missing in composer.json
- 【Idea插件】kotlin的orm框架一键生成代码框架
@font-face { font-family: octicons-link; src: url("data:font/woff;charset=utf-8;base64,d09GRgAB ...
- Java项目连接数据库Mysql报错create connection SQLException
今天编写了一个Java项目,对数据库Mysql的表进行增删改查,然后遇到了这个问题 严重: create connection SQLException, url: jdbc:mysql://loca ...
- Python爬取跑男的评论,看看大家都在看谁吧
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 以下文章来源于菜J学Python,作者: J哥 Python爬取爬取腾讯视频弹幕视频讲解 http ...
- 微博爬虫,python微博用户主页小姐姐图片内容采集爬虫
python爬虫,微博爬虫,需要知晓微博用户id号,能够通过抓取微博用户主页内容来获取用户发表的内容,时间,点赞数,转发数等数据,当然以上都是本渣渣结合网上代码抄抄改改获取的! 要抓取的微博地址:ht ...
- 悉数 Python 函数传参的语法糖
TIOBE排行榜是程序开发语言的流行使用程度的有效指标,对世界范围内开发语言的走势具有重要参考意义.随着数据挖掘.机器学习和人工智能相关概念的风行,Python一举收获2018年年度语言,这也是Pyt ...
- RestTemplate发起http请求中文乱码问题解决方案
RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); MediaType t ...
- 个人MySQL的事务特性原理学习笔记总结
目录 个人MySQL的事务特性原理笔记总结 一.基础概念 2. 事务控制语句 3. 事务特性 二.原子性 1. 原子性定义 2. 实现 三.持久性 1. 定义 2. 实现 3. redo log存在的 ...