Lodash partialRight Placeholders in Arrays

This article explores how Lodash's _.partialRight handles placeholder variables (_) when configuring arguments, with a specific focus on whether placeholders are resolved inside complex array sequences. While _.partialRight allows flexible right-to-left argument binding using positional placeholders, it treats array structures as literal values, meaning placeholders are only resolved at the top-level argument index rather than recursively within nested data structures.

How _.partialRight Resolves Placeholders

In Lodash, _.partialRight pre-binds arguments to a function starting from the right-hand side of its parameter signature. When you invoke _.partialRight(fn, ...partials), Lodash allows you to use the Lodash wrapper itself (commonly imported as _) as a placeholder to reserve specific slots for arguments supplied later.

When the partially applied function is executed:

  1. Arguments provided at execution time are scanned from left to right.
  2. The initial call-time arguments replace any placeholders defined in the partials list from left to right.
  3. Any remaining call-time arguments are prepended to the final argument list, preceding the partially applied arguments.
import _ from 'lodash';

function greet(greeting, punctuation, name) {
  return `${greeting}, ${name}${punctuation}`;
}

// '_' reserves the middle position among the partial arguments
const greetExcitedly = _.partialRight(greet, '!', _);

// 'World' fills the placeholder slot reserved by '_'
greetExcitedly('World', 'Hello'); 
// => "Hello, World!"

Behavior Inside Complex Array Sequences

A common point of confusion is whether _.partialRight traverses complex structures, such as arrays or objects, to replace nested placeholders.

Lodash does not perform a deep inspection or recursive traversal of arguments. It evaluates placeholders using a shallow reference check (arg === placeholder) strictly against the argument list passed to _.partialRight.

Top-Level Argument Sequences vs. Nested Elements

If your complex sequence is passed as a flat list of distinct function parameters, placeholders function as expected:

function processSequence(a, b, c, d) {
  return [a, b, c, d];
}

// Partially applying top-level arguments
const partialSeq = _.partialRight(processSequence, 3, _, 5);

// The argument 4 fills the placeholder '_', and 1, 2 precede the partials
partialSeq(1, 2, 4);
// Result: [1, 2, 4, 3, 5] (where 4 took the placeholder slot, 1 and 2 prepended)

However, if an array itself is passed as a single argument containing a placeholder, Lodash will not resolve it:

function processArray(items, metadata) {
  return { items, metadata };
}

// Attempting to place a placeholder inside an array literal
const partialArray = _.partialRight(processArray, 'meta-tag');
const invalidPlaceholder = _.partialRight(processArray, [1, _, 3]);

invalidPlaceholder('data', 2);
// Result:
// items: 'data'
// metadata: [1, [Function: lodash], 3]

In the example above, the placeholder _ remains the literal lodash function inside the array. Because the array is an object reference at a single argument index, _.partialRight does not inspect the contents of the array sequence.

Handling Nested Array Placeholders

If your application requires dynamic injection of values inside an array structure, you must handle the assembly manually rather than relying on Lodash's built-in partial application placeholders.

Standard techniques include: