Lodash源码阅读-takeRightWhile

Lodash 源码阅读-takeRightWhile

概述

takeRightWhile 函数用于从数组末尾提取元素,直到遇到第一个不满足条件的元素为止。它不是简单地提取固定数量元素,而是根据条件动态决定提取哪些元素,特别适合从数据末尾获取满足特定条件的连续元素。

前置学习

依赖函数

  • baseWhile:提供条件数组切片的内部函数
  • getIteratee:转换各种形式谓词为标准函数的工具

技术知识

  • 高阶函数:接收函数作为参数的编程方式
  • 谓词函数:返回布尔值的判断函数
  • 迭代器简写:Lodash 中的简写表达式
  • 数组切片:创建数组子集的操作
  • 从右向左迭代:从数组末尾开始处理元素

源码实现

javascript 复制代码
/**
 * Creates a slice of `array` with elements taken from the end. Elements are
 * taken until `predicate` returns falsey. The predicate is invoked with
 * three arguments: (value, index, array).
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Array
 * @param {Array} array The array to query.
 * @param {Function} [predicate=_.identity] The function invoked per iteration.
 * @returns {Array} Returns the slice of `array`.
 * @example
 *
 * var users = [
 *   { 'user': 'barney',  'active': true },
 *   { 'user': 'fred',    'active': false },
 *   { 'user': 'pebbles', 'active': false }
 * ];
 *
 * _.takeRightWhile(users, function(o) { return !o.active; });
 * // => objects for ['fred', 'pebbles']
 *
 * // The `_.matches` iteratee shorthand.
 * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
 * // => objects for ['pebbles']
 *
 * // The `_.matchesProperty` iteratee shorthand.
 * _.takeRightWhile(users, ['active', false]);
 * // => objects for ['fred', 'pebbles']
 *
 * // The `_.property` iteratee shorthand.
 * _.takeRightWhile(users, 'active');
 * // => []
 */
function takeRightWhile(array, predicate) {
  return array && array.length
    ? baseWhile(array, getIteratee(predicate, 3), false, true)
    : [];
}

实现思路

takeRightWhile 实现非常直接:先检查数组是否有效,然后调用 baseWhile 函数处理具体逻辑。传给 baseWhile 的四个参数分别是:原数组、转换后的谓词函数、操作模式(false 表示"提取")和方向标识(true 表示"从右向左")。这个函数从数组末尾开始,连续提取满足条件的元素,直到遇到第一个不满足条件的元素。

源码解析

参数检查

javascript 复制代码
array && array.length ? ... : []

这行代码处理边界情况:

  • 如果数组为 nullundefined 或空数组,直接返回空数组
  • 用短路表达式简洁地处理无效输入

例如:

javascript 复制代码
_.takeRightWhile(null, (x) => x > 0); // => []
_.takeRightWhile([], (x) => x > 0); // => []

迭代器处理

javascript 复制代码
getIteratee(predicate, 3);

这部分负责将各种形式的谓词转换为标准函数:

  • 数字 3 表示迭代函数接收三个参数:值、索引、原数组
  • 支持四种谓词形式:
    • 函数形式:如 x => !x.active
    • 对象匹配形式:如 {user: 'pebbles', active: false}
    • 属性值匹配形式:如 ['active', false]
    • 属性访问形式:如 'active'(检查属性是否为真值)

这种灵活性大大提高了函数的易用性:

javascript 复制代码
// 四种等效写法
_.takeRightWhile(users, (user) => !user.active);
_.takeRightWhile(users, { active: false });
_.takeRightWhile(users, ["active", false]);
_.takeRightWhile(users, "active"); // 提取属性为真的元素

baseWhile 调用

javascript 复制代码
baseWhile(array, getIteratee(predicate, 3), false, true);

这是函数核心:

  • 第一个参数是输入数组
  • 第二个参数是转换后的迭代函数
  • 第三个参数 false 指定为"take"模式(保留满足条件的元素)
  • 第四个参数 true 指定从右向左处理(从末尾开始)

baseWhile 的工作流程:

  1. 从数组末尾开始向前迭代
  2. 对每个元素应用谓词函数
  3. 只要谓词返回 true,就将元素加入结果
  4. 一遇到谓词返回 false 的元素,立即停止

例如对数组 [1, 2, 3, 4, 5] 和条件 x => x > 3

  • 从末尾元素 5 开始:满足条件,保留
  • 元素 4:满足条件,保留
  • 元素 3:不满足条件,停止
  • 结果是 [4, 5]

注意结果数组中的元素保持原数组的顺序,不会被反转。

总结

takeRightWhile 函数是 Lodash 中处理数组的实用工具,它体现了以下设计原则:

  1. 方向性处理:支持从右向左(从末尾开始)处理数组
  2. 声明式编程:用简洁的方式表达"取出什么"而非"如何取出"
  3. 功能对称性 :与 takeWhile 形成对称操作,一个从头处理,一个从尾处理
  4. 不可变性:创建新数组而非修改原数组,避免副作用

这个函数在处理时间序列数据、日志文件分析、状态追踪等场景下特别有用,让开发者能用简洁代码提取数组末尾满足条件的连续元素。

相关推荐
海晨忆2 分钟前
【Vue】v-if和v-show的区别
前端·javascript·vue.js·v-show·v-if
JiangJiang27 分钟前
🚀 Vue人看React useRef:它不只是替代 ref
javascript·react.js·面试
1024小神31 分钟前
在GitHub action中使用添加项目中配置文件的值为环境变量
前端·javascript
龙骑utr36 分钟前
qiankun微应用动态设置静态资源访问路径
javascript
Jasmin Tin Wei37 分钟前
css易混淆的知识点
开发语言·javascript·ecmascript
齐尹秦40 分钟前
CSS 列表样式学习笔记
前端
wsz777744 分钟前
js封装系列(一)
javascript
Mnxj44 分钟前
渐变边框设计
前端
用户7678797737321 小时前
由Umi升级到Next方案
前端·next.js
快乐的小前端1 小时前
TypeScript基础一
前端