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. 不可变性:创建新数组而非修改原数组,避免副作用

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

相关推荐
爱编程的喵1 分钟前
从XMLHttpRequest到Fetch:前端异步请求的演进之路
前端·javascript
喜欢吃豆3 分钟前
深入企业内部的MCP知识(三):FastMCP工具转换(Tool Transformation)全解析:从适配到增强的工具进化指南
java·前端·人工智能·大模型·github·mcp
豆苗学前端7 分钟前
手把手实现支持百万级数据量、高可用和可扩展性的穿梭框组件
前端·javascript·面试
不见_7 分钟前
不想再写周报了?来看看这个吧!
前端·命令行
yinke小琪9 分钟前
JavaScript 事件冒泡与事件捕获
前端·javascript
pany10 分钟前
写代码的节奏,正在被 AI 改写
前端·人工智能·aigc
liliangrong77713 分钟前
ES2025新特性详解
前端
gzzeason21 分钟前
Ajax:现代JS发起http通信的代名词
前端·javascript·ajax
iphone10828 分钟前
一次编码,多端运行:HTML5多终端调用
前端·javascript·html·html5
老坛0011 小时前
2025决策延迟的椭圆算子分析:锐减协同工具的谱间隙优化
前端