Lodash Invert: Mapping Duplicate Property Values

The Lodash _.invert method creates an object composed of the inverted keys and values of the input object, transforming values into keys and keys into values. When multiple properties share identical values, standard JavaScript objects require keys to remain strictly unique, leading to key collisions. This article examines how _.invert processes duplicate values through an overwrite mechanism, how Lodash safeguards against prototype vulnerabilities during key inversion, and how alternative methods like _.invertBy handle multiple keys without data loss.

The Inversion Mechanism and Key Collisions

In JavaScript, object keys are unique identifiers. When _.invert processes an object, it iterates over the object's own enumerable string-keyed properties and assigns the property value as the new object's key, with the original key becoming its corresponding value.

const source = { a: 1, b: 2, c: 1 };
const result = _.invert(source);
// result: { '1': 'c', '2': 'b' }

When duplicate values exist (such as a: 1 and c: 1), _.invert applies a deterministic "last write wins" strategy. As iteration proceeds in standard key traversal order, later keys overwrite earlier assignments matching the same value. The resulting object maintains unified, unique keys, but discarded references are permanently replaced.

Safe Key Assignment and Security Protections

Processing arbitrary property values into object keys poses security challenges, particularly regarding prototype pollution and property injection. If an input value resolves to sensitive object attributes such as __proto__, toString, or constructor, naive key assignment can manipulate object prototypes or disrupt inherited prototype methods.

Lodash mitigates these security concerns internally:

Preserving Duplicate Keys Using _.invertBy

When overwriting keys is undesirable, Lodash provides _.invertBy. Instead of reducing collisions to a single scalar value, _.invertBy groups identically named values into an array of keys.

const source = { a: 1, b: 2, c: 1 };
const grouped = _.invertBy(source);
// grouped: { '1': ['a', 'c'], '2': ['b'] }

This method uses an accumulator pattern where each unique inverted key maps to a collection, safely preserving all original mappings without dropping data. It also accepts an iteratee function, allowing dynamic transformation of generated keys prior to unification.