Lodash - Seq (序列)
Lodash - 序列方法(链式调用)
Section titled “Lodash - 序列方法(链式调用)”Lodash 允许您使用其序列方法(sequence methods)在一个值(如数组或对象)上创建操作链(chains of operations)。这使得复杂的 数据转换(data transformations) 可以采用流畅(fluent)、易读的风格编写。至关重要的是,Lodash 在其显式链式调用(explicit chains)中支持惰性求值(lazy evaluation),这意味着计算会推迟到通过 .value() 请求最终结果时才执行。通过避免创建中间数组或对象,这可以带来显著的性能提升。
使用 _.chain() 进行显式链式调用
Section titled “使用 _.chain() 进行显式链式调用”要开始一个带有惰性求值的显式链式调用,请使用 _.chain() 包装您的初始值。
| 方法与语法 | 描述 |
|---|---|
| _.chain(value) | 创建一个 lodash 包装器(wrapper)实例,启用显式链式调用。允许后续的 Lodash 方法直接在该包装器上调用。 |
| wrapper.value() | 执行链式序列并返回解析后的值。这会触发推迟(deferred)的计算。 |
| wrapper.plant(value) | 创建链包装器实例的克隆,其中 value 替换了包装的值。 |
| wrapper.commit() | 执行链式序列并返回包装后的结果(仍是一个 lodash 包装器)。 |
| _.tap(value, interceptor) | 调用 interceptor 函数,将 value 作为其参数,并返回 value。在不改变链流程的情况下检查中间结果时很有用。 |
| _.thru(value, interceptor) | 类似于 _.tap,但 interceptor 的返回值会替换链中的 value。允许将自定义函数集成到链中。 |
惰性求值示例
Section titled “惰性求值示例”考虑在一个大型数组中查找大于 5 的前两个偶数的平方:
import _ from 'lodash-es';
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
console.log('--- Eager Evaluation (Native JS / Implicit Lodash Chain) ---');const eagerResult = numbers .filter(n => { console.log('Filtering:', n); return n > 5; }) .filter(n => { console.log('Checking even:', n); return n % 2 === 0; }) .map(n => { console.log('Mapping:', n); return n * n; }) .slice(0, 2);console.log('Eager Result:', eagerResult);
console.log('\n--- Lazy Evaluation (Lodash Explicit Chain) ---');const lazyResult = _.chain(numbers) .filter(n => { console.log('Filtering:', n); return n > 5; }) .filter(n => { console.log('Checking even:', n); return n % 2 === 0; }) .map(n => { console.log('Mapping:', n); return n * n; }) .take(2) // More efficient than map().slice() in a lazy chain .value(); // Execute the chain
console.log('Lazy Result:', lazyResult);观察控制台输出。在非惰性(eager)版本中,所有数字都被过滤了两次,并且所有产生的偶数都被映射(mapped),然后才进行切片(slicing)。在惰性(lazy)版本中,Lodash 会逐个元素地通过整个链进行处理,直到满足 _.take(2) 的要求。一旦获得所需的两个结果,它就会停止处理,从而避免对数组的其余部分进行不必要的计算。
隐式链式调用
Section titled “隐式链式调用”Lodash 也支持隐式链式调用,当您调用一个 Lodash 函数并传入一个值,并且结果可以传递给另一个 Lodash 函数时,就会发生隐式链式调用。然而,隐式链式调用是非惰性的;每个步骤都会立即执行,类似于原生方法的链式调用。
// Implicit chain (EAGER evaluation)const implicitResult = _.take(_.map(_.filter(numbers, n => n % 2 === 0), n => n * n), 2);// This is less readable and performs intermediate array creation.现代替代方案
Section titled “现代替代方案”尽管功能强大,但在现代 JavaScript 中,显式链式调用(_.chain)有时被认为不那么符合习惯,通常更倾向于使用原生方法链式调用或函数组合模式(使用 _.flow 或原生函数组合等工具)来提高可读性。然而,对于大型数据集或复杂序列,惰性求值带来的性能优势仍然是使用 _.chain 的一个重要理由。
当您需要惰性求值以获得性能优势,或者当流畅的链式风格能显著提高复杂、多步转换的可读性时,请使用 Lodash 链式调用。