Lodash keyBy Duplicate Keys and Data Overwrite
When using Lodash’s _.keyBy method on a collection where
multiple elements produce the identical key, a key collision occurs
resulting in a "last-write-wins" behavior. This article covers how
_.keyBy resolves duplicate keys, what technically happens
to the overwritten values in memory, and the appropriate alternatives if
you need to retain all data.
How _.keyBy Handles
Collisions
The _.keyBy method iterates through a collection, runs
an iteratee function (or uses a property shorthand) to compute a string
key for each item, and assigns that item to the key on a newly created
object:
result[computedKey] = currentItem;Because standard JavaScript objects cannot hold duplicate keys, assigning a value to an existing key replaces the existing reference with the new one. The last element in the collection with the conflicting key becomes the final value in the returned object.
The Fate of the Overwritten Data
When an item is overwritten in _.keyBy:
- Exclusion from the Result Object: The prior item is
completely omitted from the final returned object. There is no history,
warning, or fallback mechanism within
_.keyByto preserve overwritten items. - Original Collection Remains Unchanged: Lodash functions are pure and non-destructive. The original array or collection being iterated is not mutated; the original items still exist in their initial state within the source structure.
- Garbage Collection Behavior: Within the scope of the output object, the reference to the earlier item is lost. However, the overwritten object is not immediately eligible for garbage collection if the original collection remains referenced elsewhere in memory. If the source collection was a temporary array generated dynamically (e.g., inline during a pipeline) and no other references exist, the overwritten items will be flagged and reclaimed by the JavaScript engine's garbage collector.
Example
const users = [
{ id: 'a', name: 'Alice' },
{ id: 'b', name: 'Bob' },
{ id: 'a', name: 'Alex' } // Duplicate key 'a'
];
const keyed = _.keyBy(users, 'id');
console.log(keyed);
// Output:
// {
// a: { id: 'a', name: 'Alex' },
// b: { id: 'b', name: 'Bob' }
// }In this example, the item { id: 'a', name: 'Alice' } is
assigned first, then immediately overwritten by
{ id: 'a', name: 'Alex' }. Alice's record is completely
absent from the keyed object, but remains intact in the
users array.
How to Preserve Overwritten Data
If your dataset contains duplicate keys and you cannot afford to lose
the overwritten items, use _.groupBy instead of
_.keyBy.
The _.groupBy function uses the same keying logic but
sets the value of each key to an array containing every matching item,
ensuring no data is overwritten:
const grouped = _.groupBy(users, 'id');
console.log(grouped);
// Output:
// {
// a: [{ id: 'a', name: 'Alice' }, { id: 'a', name: 'Alex' }],
// b: [{ id: 'b', name: 'Bob' }]
// }