Lodash uniqBy: Which Duplicate Is Kept?
The Lodash _.uniqBy method is widely used in JavaScript
to remove duplicate entries from an array based on a specific iteratee
function or object property. When duplicates exist, developers often
need to know which version of the item remains in the final output. This
article explains the selection mechanism of _.uniqBy,
demonstrates its behavior with code, and outlines how to retain the last
duplicate instead of the default choice.
The Selection Rule: First Occurrence Wins
When _.uniqBy processes an array, it always preserves
the first occurrence of each unique item and discards
all subsequent duplicates.
The method traverses the array sequentially from left to right (from
index 0 to array.length - 1). For each
element, it executes the provided iteratee (a property name, function,
or path) to compute a comparison key. If that computed key has not been
seen before, the item is added to the result array. If the key has
already been encountered, the current item is skipped.
Code Example
Consider an array of user objects where two entries share the same
id:
const _ = require('lodash');
const users = [
{ id: 1, name: 'Alice', status: 'pending' },
{ id: 2, name: 'Bob', status: 'active' },
{ id: 1, name: 'Alice', status: 'approved' }
];
const result = _.uniqBy(users, 'id');
console.log(result);Output:
[
{ id: 1, name: 'Alice', status: 'pending' },
{ id: 2, name: 'Bob', status: 'active' }
]In this example, the item with status: 'pending' is kept
because it appears first in the array. The second item with
id: 1 and status: 'approved' is discarded.
How to Keep the Last Occurrence Instead
Because _.uniqBy natively keeps only the first item, you
must alter the order of traversal if your application requires keeping
the latest or last occurrence.
The most common approach is to reverse a shallow copy of the array
before passing it to _.uniqBy, and optionally reverse the
result back to maintain the original relative sequence:
const _ = require('lodash');
const users = [
{ id: 1, name: 'Alice', status: 'pending' },
{ id: 2, name: 'Bob', status: 'active' },
{ id: 1, name: 'Alice', status: 'approved' }
];
// Keep the last occurrence
const result = _.uniqBy([...users].reverse(), 'id').reverse();
console.log(result);Output:
[
{ id: 2, name: 'Bob', status: 'active' },
{ id: 1, name: 'Alice', status: 'approved' }
]Summary
_.uniqByprocesses elements sequentially from index0.- The first item that generates a unique key is always preserved.
- All subsequent matching elements are discarded.
- Reversing the array prior to deduplication allows you to retain the last occurrence.