Lodash源码阅读-remove

Lodash 源码阅读-remove

概述

remove 是 Lodash 中的一个数组方法,用于移除数组中满足指定条件的所有元素,并返回这些被移除的元素组成的新数组。与过滤方法不同的是,remove 会直接修改原数组,而不是创建一个新数组。

前置学习

依赖函数

  • getIteratee:获取迭代器函数,将传入的条件转换为标准函数
  • basePullAt:从数组中移除指定索引位置的元素的基础实现

技术知识

  • 数组操作:数组元素的遍历和删除
  • 谓词函数:用于测试数组元素是否满足条件的函数
  • 副作用操作:直接修改原始数据的操作
  • 迭代器模式:使用函数对集合进行操作的设计模式

源码实现

javascript 复制代码
function remove(array, predicate) {
  var result = [];
  if (!(array && array.length)) {
    return result;
  }
  var index = -1,
    indexes = [],
    length = array.length;

  predicate = getIteratee(predicate, 3);
  while (++index < length) {
    var value = array[index];
    if (predicate(value, index, array)) {
      result.push(value);
      indexes.push(index);
    }
  }
  basePullAt(array, indexes);
  return result;
}

实现思路

remove 函数的实现思路非常直观:

  1. 首先创建一个空数组 result 用于存储将被移除的元素
  2. 如果输入数组不存在或长度为 0,直接返回空结果数组
  3. 将传入的 predicate 参数转换为标准的迭代器函数,确保它接受三个参数(值、索引、数组)
  4. 遍历数组,对每个元素应用谓词函数
  5. 如果元素满足条件(谓词函数返回真值),则:
    • 将元素添加到结果数组中
    • 记录元素的索引位置
  6. 遍历完成后,使用 basePullAt 函数批量移除所有记录的索引位置的元素
  7. 返回包含所有被移除元素的结果数组

这种实现既高效又优雅,通过先收集所有需要删除的元素和索引,然后一次性执行删除操作,避免了在遍历过程中直接修改数组可能导致的索引错位问题。

源码解析

初始化与边界检查

javascript 复制代码
var result = [];
if (!(array && array.length)) {
  return result;
}

函数首先创建一个空数组 result 用于存储将被移除的元素。然后检查输入数组是否存在且长度大于 0,如果不满足条件则提前返回空结果数组。这是一个常见的优化技巧,避免对空数组进行不必要的处理。

变量初始化

javascript 复制代码
var index = -1,
  indexes = [],
  length = array.length;

这里初始化了三个变量:

  • index:用于遍历数组的索引,初始为 -1(因为循环开始时会先自增)
  • indexes:用于记录需要删除的元素的索引位置
  • length:缓存数组长度,避免在循环中重复获取

转换谓词函数

javascript 复制代码
predicate = getIteratee(predicate, 3);

使用 getIteratee 函数将传入的 predicate 转换为标准的迭代器函数。参数 3 表示该函数应该接受三个参数:值、索引、数组。这允许用户以多种方式传入条件,如函数、对象、数组或字符串,getIteratee 会将它们统一转换为适当的函数。

遍历数组并收集满足条件的元素

javascript 复制代码
while (++index < length) {
  var value = array[index];
  if (predicate(value, index, array)) {
    result.push(value);
    indexes.push(index);
  }
}

通过 while 循环遍历数组的每个元素,对每个元素:

  1. 使用谓词函数测试元素是否满足条件
  2. 如果满足条件,将元素添加到结果数组,并记录其索引位置

这个过程不会修改原数组,只是在收集需要移除的元素和索引。

批量移除元素并返回结果

javascript 复制代码
basePullAt(array, indexes);
return result;

最后,调用 basePullAt 函数,根据收集的索引批量移除原数组中的元素。这个操作会直接修改原数组。然后返回之前收集的所有被移除元素组成的数组。

总结

remove 函数是 Lodash 中一个实用的数组操作工具,它巧妙地解决了"查找并移除满足条件的所有元素"这一常见需求。其特点包括:

  1. 原地修改:直接修改原数组,不需要额外的赋值操作
  2. 返回移除的元素:同时返回被移除的元素,便于进一步处理
  3. 批量操作:先收集所有要移除的索引,然后一次性删除,避免了遍历中修改数组的问题
  4. 灵活的条件指定:支持多种形式的条件指定,如函数、对象、数组或字符串

这个函数在需要同时获取被移除元素并更新原数组的场景中特别有用,它提供了比原生 JavaScript 数组方法更强大和便捷的功能。与 filter 方法相比,remove 方法直接修改原数组,适用于不需要保留原数组的场景,可以节省内存并简化代码。

相关推荐
fakaifa3 分钟前
【最新版】西陆健身系统源码全开源+uniapp前端
前端·小程序·uni-app·开源·php·约课小程序·健身小程序
南囝coding8 分钟前
关于我的第一个产品!
前端·后端·产品
iOS阿玮15 分钟前
别等了,今天是Xcode15时代的最后一天。
前端·app·apple
沙尘暴炒饭21 分钟前
vuex持久化vuex-persistedstate,存储的数据刷新页面后导致数据丢失
开发语言·前端·javascript
2401_8370885024 分钟前
CSS清楚默认样式
前端·javascript·css
zwjapple35 分钟前
React 的 useEffect 清理函数详解
前端·react.js·前端框架
Jewel1051 小时前
如何配置Telegram Mini-App?
前端·vue.js·app
s11show_1631 小时前
hz修改后台新增keyword功能
android·java·前端
二个半engineer2 小时前
Web常见攻击方式及防御措施
前端
co松柏2 小时前
程序员必备——AI 画技术图技巧
前端·后端·ai编程