Lodash源码阅读-basePullAt

Lodash 源码阅读-basePullAt

概述

basePullAt 是 Lodash 内部的工具函数,用于从数组中移除指定索引位置的元素。它是 _.pullAt 方法的底层实现,支持同时移除多个索引位置的元素,并且会修改原数组。

前置学习

依赖函数

  • isIndex: 判断一个值是否为有效的数组索引
  • baseUnset: 移除对象属性的内部方法(用于非数字索引)
  • splice: JavaScript 原生数组方法,用于删除数组元素

技术知识

  • 数组修改操作: 原地修改数组的方法
  • 函数绑定 : 使用 call 方法调用函数并绑定 this
  • 稀疏数组: JavaScript 中的非连续索引数组
  • 索引处理: 数组索引与对象属性的区别

源码实现

js 复制代码
function basePullAt(array, indexes) {
  var length = array ? indexes.length : 0,
    lastIndex = length - 1;

  while (length--) {
    var index = indexes[length];
    if (length == lastIndex || index !== previous) {
      var previous = index;
      if (isIndex(index)) {
        splice.call(array, index, 1);
      } else {
        baseUnset(array, index);
      }
    }
  }
  return array;
}

实现思路

basePullAt 函数的设计思路非常巧妙:

  1. 从后向前遍历索引数组,这样在删除元素时不会影响后续元素的索引位置
  2. 使用 isIndex 判断索引是否为有效的数组索引
  3. 对于有效的数组索引,使用原生的 splice 方法删除元素
  4. 对于非数字索引(对象属性),使用 baseUnset 方法删除
  5. 跳过重复的索引,避免多次尝试删除同一位置的元素
  6. 返回修改后的原数组

这种实现方式保证了高效的数组元素删除,并且处理了各种边界情况。

源码解析

让我们逐步解析 basePullAt 函数的实现:

js 复制代码
function basePullAt(array, indexes) {
  var length = array ? indexes.length : 0,
      lastIndex = length - 1;

首先,函数检查 array 是否存在,如果存在,则获取 indexes 数组的长度;如果不存在,则将长度设为 0。同时计算出最后一个索引的位置。

js 复制代码
while (length--) {
  var index = indexes[length];

函数使用了从后向前的遍历方式(length--),这样当删除前面的元素时,不会影响后面元素的索引位置。在每次循环中,获取当前要处理的索引值。

js 复制代码
if (length == lastIndex || index !== previous) {
  var previous = index;

这段代码检查当前索引是否是最后一个索引或者与前一个处理的索引不同。这是为了避免重复处理相同的索引。如果 indexes 数组中包含重复的索引,只有第一次遇到时才会执行删除操作。

js 复制代码
if (isIndex(index)) {
  splice.call(array, index, 1);
} else {
  baseUnset(array, index);
}

根据索引类型选择不同的删除方法:

  • 如果是有效的数组索引(通过 isIndex 函数判断),使用 splice.call(array, index, 1) 方法从数组中删除该位置的元素。
  • 如果不是有效的数组索引(可能是字符串属性名),使用 baseUnset(array, index) 方法删除该属性。
js 复制代码
}
}
return array;

最后,函数返回修改后的原数组。

应用示例

js 复制代码
var array = ["a", "b", "c", "d"];
basePullAt(array, [1, 3]);
// 移除索引 1 和 3 的元素
// array 变成 ['a', 'c']

var obj = { 0: "a", 1: "b", foo: "bar" };
basePullAt(obj, [1, "foo"]);
// 移除索引 1 和属性 'foo'
// obj 变成 { '0': 'a' }

总结

basePullAt 函数是一个精巧的数组元素删除工具,它具有以下几个设计亮点:

  1. 逆序遍历: 从后向前删除元素,避免索引位置变化导致的问题。
  2. 类型判断: 区分处理数组索引和对象属性,使用不同的删除方法。
  3. 去重处理: 避免对重复索引进行多次操作,提高效率。
  4. 原地修改: 直接修改原数组,不创建新数组,节省内存。

这个函数体现了 Lodash 在处理数组操作时的细致考量,包括性能优化和边界情况的处理。理解这种实现方式对于我们设计自己的数组操作函数也有很大的启发。

相关推荐
apcipot_rain4 小时前
【应用密码学】实验五 公钥密码2——ECC
前端·数据库·python
油丶酸萝卜别吃4 小时前
OpenLayers 精确经过三个点的曲线绘制
javascript
ShallowLin4 小时前
vue3学习——组合式 API:生命周期钩子
前端·javascript·vue.js
Nejosi_念旧5 小时前
Vue API 、element-plus自动导入插件
前端·javascript·vue.js
互联网搬砖老肖5 小时前
Web 架构之攻击应急方案
前端·架构
pixle05 小时前
Vue3 Echarts 3D饼图(3D环形图)实现讲解附带源码
前端·3d·echarts
麻芝汤圆6 小时前
MapReduce 入门实战:WordCount 程序
大数据·前端·javascript·ajax·spark·mapreduce
juruiyuan1117 小时前
FFmpeg3.4 libavcodec协议框架增加新的decode协议
前端
Peter 谭8 小时前
React Hooks 实现原理深度解析:从基础到源码级理解
前端·javascript·react.js·前端框架·ecmascript
周胡杰8 小时前
鸿蒙接入flutter环境变量配置windows-命令行或者手动配置-到项目的创建-运行demo项目
javascript·windows·flutter·华为·harmonyos·鸿蒙·鸿蒙系统