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:

  1. 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 _.keyBy to preserve overwritten items.
  2. 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.
  3. 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' }]
// }