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)

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]:

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:

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.