鲁迅说过:只有阅读过优秀库源码的人,才能配的上是真正的勇士。

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函数所依赖的工具函数就多几个。

  1. arrayPush数组添加方法
  2. copyArray拷贝数组元素
  3. 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;

总结

  1. ++index和index++不同之处,++i就是先加后用,i++就是先用后加。前置++下标不会越界,后置++下标越界。
  2. lodash库操作数组一般都不会影响原有数组。

阅读lodash源码之旅数组方法篇-compact和concat的更多相关文章

  1. 手把手带你阅读Mybatis源码(三)缓存篇

    前言 大家好,这一篇文章是MyBatis系列的最后一篇文章,前面两篇文章:手把手带你阅读Mybatis源码(一)构造篇 和 手把手带你阅读Mybatis源码(二)执行篇,主要说明了MyBatis是如何 ...

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

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

  3. 手把手带你阅读Mybatis源码(一)构造篇

    前言 今天会给大家分享我们常用的持久层框架——MyBatis的工作原理和源码解析,后续会围绕Mybatis框架做一些比较深入的讲解,之后这部分内容会归置到公众号菜单栏:连载中…-框架分析中,欢迎探讨! ...

  4. 手把手带你阅读Mybatis源码(二)执行篇

    前言 上一篇文章提到了MyBatis是如何构建配置类的,也说了MyBatis在运行过程中主要分为两个阶段,第一是构建,第二就是执行,所以这篇文章会带大家来了解一下MyBatis是如何从构建完毕,到执行 ...

  5. 从源码角度看finish()方法的执行流程

    1. finish()方法概览 首先我们来看一下finish方法的无参版本的定义: /** * Call this when your activity is done and should be c ...

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

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

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

    卑鄙是卑鄙者的通行证,高尚是高尚者的墓志铭. --北岛<回答> 看北岛就是从这两句诗开始的,高尚者已死,只剩卑鄙者在世间横行. 本文为读 lodash 源码的第一篇,后续文章会更新到这个仓 ...

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

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

  9. lodash源码分析之Hash缓存

    在那小小的梦的暖阁,我为你收藏起整个季节的烟雨. --洛夫<灵河> 本文为读 lodash 源码的第四篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbo ...

随机推荐

  1. Java之String重点解析

    String s = new String("abc")这段代码创建了几个对象呢?s=="abc"这个判断的结果是什么?s.substring(0,2).int ...

  2. Python高级语法-GIL-理解(4.1.1)

    @ 目录 1.结论 2.代码 关于作者 1.结论 当一个py文件执行多进程的时候,是真的在并发 当一个文件在使用多线程的时候,伪并发,在同一时刻只有一个线程执行,因为GIL Guido都说了,不好除这 ...

  3. 带你学习Python-基础知识的框架梳理

    对于编程初学者来说,在刚刚开始学习Python语言的时候,需要学习的内容有不少,比如计算机原理.网络.Web前端.后端.架构. 数据库都是必须掌握的知识点.因此初学者常常会陷入"只见树木,不 ...

  4. Core3.0中Swagger使用JWT

    前言 学习ASP.NETCore,原链接 https://www.cnblogs.com/laozhang-is-phi/p/9511869.html 原教程是Core2.2,后期也升级到了Core3 ...

  5. codeblocks opengl glew freeglut 2020.11.15

    https://wenku.baidu.com/view/28cd5ebfaf1ffc4fff47accf.html 一下为测试代码 /* ============================== ...

  6. Linux嵌入式学习-ds18b20驱动

    ds18b20的时序图如下: 复位时序: 读写时序: 以下是程序代码: #include <linux/module.h> #include <linux/init.h> #i ...

  7. 异步技巧之CompletableFuture

    摘自--https://juejin.im/post/5b4622df5188251ac9766f47 异步技巧之CompletableFuture 1.Future接口 1.1 什么是Future? ...

  8. 2018年第九届蓝桥杯B组(201806-----递增三元组)

    给定三个整数数组 A = [A1, A2, - AN], B = [B1, B2, - BN], C = [C1, C2, - CN], 请你统计有多少个三元组(i, j, k) 满足: 1 < ...

  9. 我与CSDN的第一百天

  10. Spring Security OAuth2.0认证授权二:搭建资源服务

    在上一篇文章[Spring Security OAuth2.0认证授权一:框架搭建和认证测试](https://www.cnblogs.com/kuangdaoyizhimei/p/14250374. ...