How Lodash Iteratee Converts Strings and Objects
In the Lodash JavaScript library, collection methods such as
_.map, _.filter, and _.find do
not require you to provide an explicit callback function. Instead,
Lodash uses its internal adapter function, _.iteratee, to
automatically transform strings, objects, and arrays into reusable
callback functions. This article explains how _.iteratee
detects different data types, the specific Lodash helpers it delegates
to under the hood, and how these transformations streamline common data
manipulation tasks.
The Role of _.iteratee
Whenever a Lodash method accepts a callback parameter (commonly
documented as [iteratee=_.identity]), it wraps that
argument with _.iteratee before processing the
collection.
If the provided argument is already a function,
_.iteratee simply returns it unchanged. However, if the
argument is a string, an object, or an array, _.iteratee
acts as a factory, matching the input type against specific internal
constructors to generate a specialized predicate or accessor
function.
Converting Strings: Property Shorthand
When passed a string (or a property path), _.iteratee
delegates the transformation to _.property.
The generated function takes an object from the collection and returns the value at the specified key. It also supports deep dot-notation paths and array bracket notation.
// You write:
_.map(users, 'profile.name');
// _.iteratee transforms the string into:
_.map(users, _.property('profile.name'));
// Equivalent standard JavaScript:
users.map(user => user?.profile?.name);Under the hood, _.property uses Lodash's path-retrieval
logic (similar to _.get), ensuring that nested properties
do not throw TypeError exceptions if intermediate
properties are null or undefined.
Converting Objects: Matches Shorthand
When passed a plain JavaScript object, _.iteratee
delegates to _.matches.
This generates a predicate function that performs a deep partial
comparison against each item in the collection using
_.isMatch. The generated function returns true
only if the evaluated item contains identical keys and equivalent nested
values to those defined in the target object.
// You write:
_.filter(users, { active: true, role: 'admin' });
// _.iteratee transforms the object into:
_.filter(users, _.matches({ active: true, role: 'admin' }));
// Equivalent standard JavaScript:
users.filter(user => user.active === true && user.role === 'admin');This shorthand allows you to filter or find records based on deep object structures without manually chaining multiple equality checks.
Converting Two-Element Arrays: Property-Value Matching
When an array containing a key-value pair [key, value]
is supplied, _.iteratee transforms it using
_.matchesProperty.
This returns a predicate function that checks whether the property at the given key matches the specified value.
// You write:
_.find(users, ['status', 'pending']);
// _.iteratee transforms the array into:
_.find(users, _.matchesProperty('status', 'pending'));
// Equivalent standard JavaScript:
users.find(user => user.status === 'pending');Like _.property, the key parameter in
_.matchesProperty can be a nested path (e.g.,
['account.status', 'pending']).
The Fallback:
_.identity
If an iteratee argument is omitted, or if it is null or
undefined, _.iteratee defaults to
_.identity. The _.identity function simply
returns the first argument provided to it
(value => value). This is useful for flattening
collections, filtering out falsy values via
_.filter(array, Boolean) behavior, or extracting identical
values.
Summary of the Transformation Pipeline
When any value enters _.iteratee, Lodash evaluates it in
this order:
- Functions: Returned directly without modification.
- Plain Objects: Wrapped with
_.matches(value)for deep partial equality. - Arrays: Wrapped with
_.matchesProperty(value[0], value[1])for key-value checks. - Strings / Numbers / Symbols: Wrapped with
_.property(value)for property extraction. - Null / Undefined / Other: Replaced with
_.identityto return elements as-is.