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

相关推荐
小屁孩大帅-杨一凡36 分钟前
一个简单点的js的h5页面实现地铁快跑的小游戏
开发语言·前端·javascript·css·html
读心悦41 分钟前
CSS 布局系统深度解析:从传统到现代的布局方案
前端·css
椒盐螺丝钉1 小时前
CSS盒子模型:Padding与Margin的适用场景与注意事项
前端·css
萧鼎2 小时前
构建全栈 Web 应用的新选择:NextPy 技术详解与实战指南
前端
purpleseashell_Lili2 小时前
配置别名路径 @
javascript·react
这个一个非常哈2 小时前
VUE篇之自定义组件使用v-model
前端·javascript·vue.js
purpleseashell_Lili2 小时前
react 基本写法
java·服务器·前端
哎哟喂_!2 小时前
Node.js 循环依赖问题详解:原理、案例与解决方案
前端·chrome·node.js
热爱前端的小君同学3 小时前
长按拖拽移动的vue3组件
前端·javascript·vue.js
Rhys..3 小时前
如何禁止chrome自动更新
前端·chrome