How to Use Lodash _.unary with _.map

The Lodash _.unary method simplifies transforming collections with _.map by restricting a target function to accept only a single argument. When functions with optional parameters—such as JavaScript's built-in parseInt—are passed directly to _.map, unexpected behavior often occurs because _.map supplies extra arguments like the current index and the entire collection. By wrapping these callback functions in _.unary, developers can prevent unwanted parameter passing, avoid boilerplate arrow functions, and write cleaner, bug-free functional code.

The Problem with Default Iteration Arguments

Both JavaScript's native Array.prototype.map and Lodash's _.map pass three arguments to their iteratee callback on each iteration:

  1. value: The current element being processed.
  2. index: The index or key of the current element.
  3. collection: The entire array or object being traversed.

This design causes subtle bugs when passing a function that accepts optional arguments. The most famous example is parseInt(string, radix). When passed directly to map:

['6', '8', '10'].map(parseInt);
// Output: [6, NaN, 2]

The unexpected result happens because parseInt receives the array index as its radix (base) parameter:

How _.unary Resolves the Issue

The _.unary method creates a new function that caps the arity (the number of accepted arguments) of the provided function to exactly one. Any secondary or tertiary arguments supplied by _.map are completely ignored.

const _ = require('lodash');

const safeParseInt = _.unary(parseInt);

_.map(['6', '8', '10'], safeParseInt);
// Output: [6, 8, 10]

Under the hood, _.unary(fn) acts like a wrapper: (arg) => fn(arg). When _.map calls the wrapped function with ('8', 1, array), _.unary discards 1 and array, forwarding only '8' to parseInt.

Eliminating Boilerplate

Before _.unary, the standard workaround was manually writing an anonymous function or arrow function to isolate the first argument:

_.map(['6', '8', '10'], (num) => parseInt(num));

While functional, this approach introduces boilerplate and manual parameter naming. Using _.unary provides a point-free, declarative alternative:

_.map(['6', '8', '10'], _.unary(parseInt));

Key Takeaways