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

相关推荐
Moment几秒前
富文本编辑器技术选型,到底是 Prosemirror 还是 Tiptap 好 ❓❓❓
前端·javascript·面试
xkxnq5 分钟前
第二阶段:Vue 组件化开发(第 18天)
前端·javascript·vue.js
晓得迷路了6 分钟前
栗子前端技术周刊第 112 期 - Rspack 1.7、2025 JS 新星榜单、HTML 状态调查...
前端·javascript·html
怕浪猫9 分钟前
React从入门到出门 第五章 React Router 配置与原理初探
前端·javascript·react.js
jinmo_C++9 分钟前
从零开始学前端 · HTML 基础篇(一):认识 HTML 与页面结构
前端·html·状态模式
鹏多多16 分钟前
前端2025年终总结:借着AI做大做强再创辉煌
前端·javascript
哈__19 分钟前
React Native 鸿蒙跨平台开发:Vibration 实现鸿蒙端设备的震动反馈
javascript·react native·react.js
WebGISer_白茶乌龙桃21 分钟前
Cesium实现“悬浮岛”式,三维立体的行政区划
javascript·vue.js·3d·web3·html5·webgl
小Tomkk24 分钟前
⭐️ StarRocks Web 使用介绍与实战指南
前端·ffmpeg
不一样的少年_28 分钟前
产品催: 1 天优化 Vue 官网 SEO?我用这个插件半天搞定(不重构 Nuxt)
前端·javascript·vue.js