源码学习——lodash(二)

前言

上节我们介绍了lodash三个方法的源码,本节我们继续来看数组相关方法。

difference

difference可以将两个数组进行对比,返回一个过滤掉特定值的新数组。它有两个参数,一个为检查数组,一个为排除数组。

js 复制代码
   _.difference(array, [values])
   array 检查数组
   [values] 排除数组
   _.difference([1,2],[2,3]) //[1]

该方法有点像filter的升级版,具体的源码如下:

源码非常的简单,就是一个三目运算,下面我们就解析一下里面的方法:

  1. isArrayLikeObject检查参数是否为数组,该方法是lodash基础方法,源码写的比较分散,这里我合并了一下方便查阅。
    判断思路很简单,先判断是否为Object,然后判断是否为数组,都是用type of就行了简单判断,其中数组的判断加上了isLength,该方法就是校验是否正整数并加上了长度校验。数组校验方法有很多,一般我们直接用isArray就判断了,之所以lodash不用,猜想还是想坚持避免使用数组方法。
  2. baseDifference核心方法,返回result。这里传了两个参数,其中第二个参数用baseFlatten将排除数组进行了扁平化的处理。baseDifference总共有四个参数,iteratee与comparator是后两个方法相关,源码逻辑是先进行了判断处理:

对于baseDifference我们直接看后面的源码:

  • 用for of循环检查数组array,接着进入判断,isCommon就是baseDifference逻辑。
  • 用while循环排除数组values,当排除数组的值等于当前元素时,就用continue跳过此次循环,不等就添加到result中。这里注意一下判断有一个computed === computed ,computed是处理过后的元素,为什么会判断严格相等一下呢?其实这里就是为了判断一些特殊类型比如NaN,细节拉满。

differenceBy

differenceBy是在difference的基础上加上了iteratee迭代器,数组中的元素会先经过迭代器处理,然后再进行比较,比如对象数组,我们可以指定比较的key。

js 复制代码
_.differenceBy([{id:1,{id:2}],[{id:1}],'x') //[{id:2}]

该方法源码就是在difference基础上加了对迭代器的判断,核心方法还是baseDifference。

回到上面baseDifference源码中,当存在iteratee时,会利用map方法对元素进行处理,values会在循环前进行处理,而array的值是在循环中进行处理的,后面逻辑都是一样的。

differenceWith

differenceWith是加上了comparator比较器参数,comparator有两个参数,一个是array的值,一个是values的值,comparator会调用每个值按照比较条件将数据进行过滤。

js 复制代码
// 去掉相等的
_.differenceWith([1,2],[1],_.isEqual) //[2]

很简单,我们还是继续研究baseDifference,comparator逻辑相对复杂点,先定义了isCommon将其与difference区分开,然后采用includes方法进行比较判断,comparator对应的includes是arrayIncludesWith

通过for of循环array元素,与目标target执行comparator比较器,这就是isCommon对应else if的内容,条件不成立的就会被添加到result。

总结

上述三个方法都是在baseDifference基础上进行实现的,所以baseDifference方法考虑得很周全。三种方法都是比较过滤两个数组的,我们碰到合适的需求可以用这三种方法。

相关推荐
sir.山20 分钟前
在 Vue 3 项目中使用 Mock 数据
前端·vue.js·vue3·vite
李剑一30 分钟前
华为新上Pura X View阔直板手机,特殊屏幕比例设备下,前端应该怎么去适配更完美?送你一套完整工具代码
前端
01_ice40 分钟前
html个人简历展示
前端·html
程序员爱钓鱼1 小时前
Rust where详解:让泛型与Trait约束更加清晰
前端·后端·rust
zzzzzz3102 小时前
react-bits 为什么会吸引前端开发者:别把动效当装饰,先把它当成页面能力
前端·react.js·动效
风月说与山鬼4 小时前
二、React入口文件(main.jsx)
前端·react.js
东风破_9 小时前
Docker 基础:为什么需要容器?
前端·后端·nginx
东风破_9 小时前
Docker 实战:使用 Nginx 作为容器入口代理 Node 服务
前端·后端·nginx
你别说话了10 小时前
Vue项目解决跨域
前端·javascript·vue.js
指尖时光.10 小时前
Three.js 超全入门综合案例
开发语言·javascript·ecmascript