Duplicate Keys in Lodash mapKeys Explained
When using the _.mapKeys function in Lodash, returning
identical string keys for multiple properties causes the subsequent keys
to overwrite the earlier ones. Because standard JavaScript objects
cannot maintain duplicate keys, Lodash assigns the mapped key to the
accumulator object sequentially, meaning the final object will only
retain the value of the last evaluated property that produced that
duplicate key, effectively causing earlier associated values to be
lost.
The Overwriting Mechanism
The _.mapKeys method iterates over an object’s own
enumerable string-keyed properties, applying a transformation function
to each key to produce a new key while keeping the original values
intact. Internally, Lodash constructs a new empty object and assigns
each transformed key along with its original value using standard object
property assignment:
result[newKey] = value;Because of this direct assignment, when multiple source properties evaluate to the same target key, the property assignment quietly overrides whichever value was previously mapped to that key.
Code Example
Consider an example where two distinct properties produce the same key after applying the iteratee function:
const _ = require('lodash');
const users = {
a: { name: 'Alice', role: 'admin' },
b: { name: 'Bob', role: 'editor' },
c: { name: 'Charlie', role: 'admin' }
};
// Mapping keys to the user's role
const byRole = _.mapKeys(users, (value) => value.role);
console.log(byRole);
// Output:
// {
// admin: { name: 'Charlie', role: 'admin' },
// editor: { name: 'Bob', role: 'editor' }
// }In this case, both property a and property
c returned the key 'admin'. Because
c was processed after a, its value overrode
the entry for a.
Property Iteration Order
The specific value that persists depends entirely on the traversal order of the source object's keys. Under the ECMAScript specification, standard string keys are traversed in the chronological order of their creation (insertion order), while integer-like keys are traversed first in ascending numerical order. Lodash follows this standard iteration behavior. Consequently, the property inserted or defined latest among the conflicting set will be the one retained.
Alternatives for Preserving Conflicting Values
If preserving data across duplicate mapped keys is required,
_.mapKeys is not the appropriate utility. Instead, use
patterns that group matching keys together:
_.groupBy: Groups elements by the result of the iteratee function, placing values with matching keys into arrays._.reduceor_.transform: Provides manual control over the accumulator, allowing values with matching keys to be merged, appended to arrays, or renamed dynamically to prevent silent data loss.