Lodash - Seq
Lodash - Sequence Methods (Chaining)
Section titled “Lodash - Sequence Methods (Chaining)”Lodash allows you to create ‘chains’ of operations on a value (like an array or object) using its sequence methods. This enables a fluent, readable style for complex data transformations. Crucially, Lodash supports lazy evaluation in its explicit chains, meaning computations are deferred until the final result is requested via .value(). This can lead to significant performance improvements by avoiding the creation of intermediate arrays or objects.
Explicit Chaining with _.chain()
Section titled “Explicit Chaining with _.chain()”To start an explicit chain with lazy evaluation, wrap your initial value with _.chain().
| Method & Syntax | Description |
|---|---|
| _.chain(value) | Creates a lodash wrapper instance that enables explicit chaining. Allows subsequent Lodash methods to be called directly on the wrapper. |
| wrapper.value() | Executes the chained sequence and returns the resolved value. This triggers the deferred computations. |
| wrapper.plant(value) | Creates a clone of the chain wrapper instance with value replacing the wrapped value. |
| wrapper.commit() | Executes the chained sequence and returns the wrapped result (still a lodash wrapper). |
| _.tap(value, interceptor) | Invokes interceptor with the value as its argument and returns value. Useful for inspecting intermediate results within a chain without altering the chain’s flow. |
| _.thru(value, interceptor) | Like _.tap, but the interceptor’s return value replaces value in the chain. Allows integrating custom functions into the chain. |
Lazy Evaluation Example
Section titled “Lazy Evaluation Example”Consider finding the squares of the first two even numbers greater than 5 in a large array:
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);Observe the console output. In the eager version, all numbers are filtered twice, and all resulting even numbers are mapped, before slicing. In the lazy version, Lodash processes elements one by one through the entire chain until _.take(2) is satisfied. It stops processing as soon as it has the required two results, avoiding unnecessary computations on the rest of the array.
Implicit Chaining
Section titled “Implicit Chaining”Lodash also supports implicit chaining when you call a Lodash function with a value, and the result can be passed to another Lodash function. However, implicit chaining is not lazy; each step is executed immediately, similar to native method chaining.
// 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.Modern Alternatives
Section titled “Modern Alternatives”While powerful, explicit chaining (_.chain) is sometimes seen as less idiomatic in modern JavaScript, where native method chaining or functional composition patterns (using tools like _.flow or native function composition) are often preferred for readability. However, the performance benefits of lazy evaluation for large datasets or complex sequences remain a compelling reason to use _.chain.
Use Lodash chaining when you need lazy evaluation for performance or when the fluent style significantly improves the readability of complex, multi-step transformations.