How to Reorder Arguments Using Lodash rearg
This article provides an overview of the _.rearg method
in the Lodash JavaScript library, detailing how it rearranges function
arguments based on an array of specified indexes. You will learn the
mechanics behind this functional programming utility, observe practical
code demonstrations, and understand common use cases such as adapting
mismatched callback signatures and improving function composition.
Understanding Lodash
_.rearg
The _.rearg method creates a wrapper function that
invokes the original function with its arguments rearranged according to
a designated sequence of indexes. It is particularly useful when you
need to adapt an existing function to work with APIs or higher-order
functions that provide arguments in an incompatible order.
Syntax
_.rearg(func, indexes)func(Function): The original function whose arguments you want to rearrange.indexes(Array|...number): The arranged argument indexes. This can be passed as a single array of numbers or as individual numeric arguments.
How Index Mapping Works
When using _.rearg, the position within the
indexes array corresponds directly to the parameter
position in the original function. The value at that position defines
which incoming argument from the caller should be used.
For example, if indexes is set to
[2, 0, 1]:
- Parameter 0 of the target function receives the caller's argument at
index
2. - Parameter 1 of the target function receives the caller's argument at
index
0. - Parameter 2 of the target function receives the caller's argument at
index
1.
Basic Example
Consider a function that formats three items in a specific order:
const _ = require('lodash');
function formatNames(first, second, third) {
return `${first} -> ${second} -> ${third}`;
}
// Reorder so that:
// Original param 0 gets caller's arg 1
// Original param 1 gets caller's arg 2
// Original param 2 gets caller's arg 0
const reorderedFormat = _.rearg(formatNames, [1, 2, 0]);
console.log(reorderedFormat('A', 'B', 'C'));
// Output: "B -> C -> A"In this case:
- Calling
reorderedFormat('A', 'B', 'C')passes'B'(index 1) tofirst. 'C'(index 2) is passed tosecond.'A'(index 0) is passed tothird.
Handling Partial Indexes and Out-of-Bound Arguments
If the indexes array contains fewer entries than the
arguments passed to the wrapper, only the arguments matching the defined
indexes will be forwarded to the original function:
function listArgs(a, b) {
return [a, b];
}
const takeSelected = _.rearg(listArgs, [2, 0]);
console.log(takeSelected('zero', 'one', 'two', 'three'));
// Output: ['two', 'zero']Any extra arguments that are not mapped in the indexes
list are dropped and will not reach the target function. If an index
refers to an argument that the caller did not supply,
undefined is passed in its place.
Practical Use Case: Adapting Callback Signatures
A common scenario for _.rearg is adapting callback
signatures for libraries that expect parameters in different orders. For
example, standard Node.js callbacks use (err, data), while
some third-party libraries pass (data, err).
function nodeStyleCallback(err, data) {
if (err) {
console.error('Error occurred:', err);
return;
}
console.log('Result:', data);
}
// Adapt a function that receives (data, err) to (err, data)
const adaptedCallback = _.rearg(nodeStyleCallback, [1, 0]);
// Simulating a call from an alternative API:
adaptedCallback('Success payload', null);
// Output: "Result: Success payload"Using _.rearg eliminates the need to write boilerplate
anonymous wrapper functions just to flip or reorganize incoming
parameters.