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 方法直接修改原数组,适用于不需要保留原数组的场景,可以节省内存并简化代码。

相关推荐
海天胜景19 分钟前
vue3 获取选中的el-table行数据
javascript·vue.js·elementui
翻滚吧键盘39 分钟前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
苦夏木禾43 分钟前
js请求避免缓存的三种方式
开发语言·javascript·缓存
超级土豆粉1 小时前
Turndown.js: 优雅地将 HTML 转换为 Markdown
开发语言·javascript·html
秃了也弱了。1 小时前
Chrome谷歌浏览器插件ModHeader,修改请求头,开发神器
前端·chrome
乆夨(jiuze)1 小时前
记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。
前端·javascript·vue.js
忧郁的蛋~2 小时前
HTML表格导出为Excel文件的实现方案
前端·html·excel
小彭努力中2 小时前
141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
前端·javascript·vue.js·交互
然我2 小时前
别再只用 base64!HTML5 的 Blob 才是二进制处理的王者,面试常考
前端·面试·html
NanLing2 小时前
【纯前端推理】纯端侧 AI 对象检测:用浏览器就能跑的深度学习模型
前端