Lodash源码阅读-pullAt

Lodash 源码阅读-pullAt

概述

pullAt 是 Lodash 中的一个数组操作函数,用于移除数组中指定索引位置的元素,并返回由被移除元素组成的新数组。与其他数组操作函数不同,pullAt 会直接修改原数组(即具有副作用),这使得它在需要同时获取被移除元素并更新原数组的场景中特别有用。

前置学习

依赖函数

  • flatRest:将函数的 rest 参数展平的特殊版本
  • baseAt:根据指定的路径从对象中获取值的基础实现
  • basePullAt:从数组中移除指定索引位置元素的基础实现
  • arrayMap:数组映射函数,类似于 Array.prototype.map
  • isIndex:检查一个值是否是有效的数组索引
  • compareAscending:用于升序排序的比较函数

技术知识

  • 函数包装与高阶函数:理解 flatRest 如何包装函数
  • 数组操作:了解数组元素的移除及相关操作
  • 类型转换:了解如何使用一元加号 (+) 将值转换为数字
  • 排序算法:了解为什么需要对索引进行排序

源码实现

javascript 复制代码
var pullAt = flatRest(function (array, indexes) {
  var length = array == null ? 0 : array.length,
    result = baseAt(array, indexes);

  basePullAt(
    array,
    arrayMap(indexes, function (index) {
      return isIndex(index, length) ? +index : index;
    }).sort(compareAscending)
  );

  return result;
});

实现思路

pullAt 函数的实现思路可以分为三个主要步骤:

  1. 提取要移除的元素:使用 baseAt 函数从原数组中获取指定索引处的元素,并将这些元素作为结果数组保存
  2. 处理索引:将所有索引转换为合适的格式(确保数字索引)并按升序排序
  3. 移除元素:使用 basePullAt 函数从原数组中按照处理后的索引移除元素

这种实现确保了即使在移除多个元素的情况下,也能正确地维护索引关系,避免因为数组长度变化导致的索引错位问题。

源码解析

函数包装

javascript 复制代码
var pullAt = flatRest(function (array, indexes) {
  // 函数体...
});

pullAt 使用 flatRest 函数包装,这意味着它接受可变数量的参数,并将第一个参数后的所有参数合并为一个展平的数组。例如:

  • pullAt(array, 1, 2, 3) 中,indexes 会被处理为 [1, 2, 3]
  • pullAt(array, [1, 2], [3]) 中,indexes 会被处理为 [1, 2, 3]

这种设计使函数调用更加灵活。

初始化变量

javascript 复制代码
var length = array == null ? 0 : array.length,
  result = baseAt(array, indexes);

这段代码做了两件事:

  1. 获取数组长度:如果 arraynullundefined,则设置 length 为 0,否则获取数组的实际长度
  2. 使用 baseAt 函数获取指定索引处的元素值:这些值将作为函数的返回值

处理索引并移除元素

javascript 复制代码
basePullAt(
  array,
  arrayMap(indexes, function (index) {
    return isIndex(index, length) ? +index : index;
  }).sort(compareAscending)
);

这段代码负责从数组中移除元素,主要步骤为:

  1. 处理索引:使用 arrayMap 遍历 indexes 数组

    • 对于每个索引,检查它是否是有效的数组索引(使用 isIndex 函数)
    • 如果是有效索引,使用一元加号 (+) 将其转换为数字(处理字符串索引如 "1")
    • 如果不是有效索引,保持原样(可能是属性路径)
  2. 排序索引:使用 compareAscending 函数对索引进行升序排序

    • 这一步很重要,因为从数组中移除元素时,较大索引处的元素应该先被移除,以避免索引错位
  3. 移除元素:调用 basePullAt 函数,根据排序后的索引从数组中移除元素

返回结果

javascript 复制代码
return result;

最后,函数返回由被移除元素组成的数组,这个数组是在函数开始时通过 baseAt 计算的。

总结

pullAt 函数是 Lodash 中一个强大的数组操作工具,它允许开发者同时完成两个操作:

  1. 从数组中移除指定索引处的元素(修改原数组)
  2. 获取被移除的元素(返回新数组)

这种设计体现了几个重要的编程原则:

  1. 分治策略:将复杂操作分解为获取元素和移除元素两个步骤,分别由专门的函数处理
  2. 索引排序:通过对索引进行排序,确保在有多个索引时能够正确处理元素移除
  3. 类型处理:对索引进行类型检查和转换,增强函数的健壮性
  4. API 设计 :使用 flatRest 提供灵活的参数格式,改善用户体验

虽然直接修改原数组违背了函数式编程中的不可变性原则,但这种设计对于需要同时获取移除元素和更新原数组的场景非常有用,提供了简洁的解决方案。如果需要保持原数组不变,可以先复制数组,然后对副本使用 pullAt

相关推荐
加班是不可能的,除非双倍日工资2 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi3 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip3 小时前
vite和webpack打包结构控制
前端·javascript
excel4 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼4 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy4 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT4 小时前
promise & async await总结
前端
Jerry说前后端4 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
画个太阳作晴天5 小时前
A12预装app
linux·服务器·前端