Explain Codes LogoExplain Codes Logo

Remove duplicate values from JS array

javascript
deduplication
performance
lodash
Alex KataevbyAlex Kataev·Aug 20, 2024
TLDR

For swift duplicate elimination, remember your new BFF: Set.

let uniqueArray = [...new Set([1, 2, 2, 3, 4, 4, 5])]; // Quick transformation: [1, 2, 3, 4, 5]

Set provides uniqueness, ... aka spread operator converts it back into an array.

Optimized approaches sorted by use-case

Performance-sensitive scenarios

In context of large data or when performance is paramount, favor a hash table setup or a loop-driven solution:

// Ultra-fast runner, Usain Bolt would approve! function uniq_fast(array) { const seen = {}; return array.filter(item => seen.hasOwnProperty(item) ? false : (seen[item] = true)); }

This exploits constant-time O(1) operations, leading to time-efficient execution even with vast data.

Dealing with objects

When your array hosts objects, deduplication based on specific property values becomes a puzzle:

// Sherlock Holmes has got nothing on this detective function! function uniqBy(array, key) { const seen = new Set(); return array.filter(item => { const keyValue = item[key]; return seen.has(keyValue) ? false : seen.add(keyValue); }); }

This preserves first occurrence of objects carrying a specific unique key.

Order is the law

When maintaining original order is key to functionality:

// A dedicated order-freak function coming your way! uniqueArray = array.reduce((acc, curr) => acc.includes(curr) ? acc : [...acc, curr], []);

Reduce, paired with includes, delivers a neat-n-clean syntax to maintain order.

Catering to complex data types

Primitives vs. objects

In situations where mixed data types can induce type coercion, use a serializer such as JSON:

// "1" is not 1, 'One String' to rule them all! let uniqueArray = [...new Set(array.map(JSON.stringify))].map(JSON.parse);

This retains difference between 1 and "1".

Infinite sequences and generator functions

Handling infinite sequences? Make way for generators:

// I can go on forever, or can I? function* uniqIter(a) { let seen = new Set(); for (let item of a) { if (!seen.has(item)) { seen.add(item); yield item; } } }

This allows for lazy evaluation and significant memory efficiency.

Utilizing library and framework functions

The Underscore and Lodash advantage

Both Underscore.js and lodash offer utility belt with _.uniq() function:

_.uniq(array); // Deduplication, now 'lodash' style!

These libraries are known for their readability and optimized method sets.

Bliss for jQuery users

For the lovers of jQuery:

// jQuery. The name's enough! $.uniqArray = (a) => $.grep(a, (item, pos) => $.inArray(item, a) === pos);

The duo of $.grep and $.inArray ensures that array remains free of duplicates.

Mastery of deduplication techniques

Complex conditions and instance preservation

When you want to discard duplicates based on complex criteria or persist first or last occurrence of objects:

// These functions can juggle, literally! function uniqByKeepFirst(data, key) { // Implementation details } function uniqByKeepLast(data, key) { // Implementation details }

With customized functions, deduplication is adjustable to needs.

Sort-first for performance

Speed up deduplication by sorting array first:

// Fast & Furious deduplication in action! uniqueArray = array.sort().reduce((acc, curr) => (acc[acc.length-1] !== curr) ? [...acc, curr] : acc, []);

Capitalizing on sorted data, such methods ensure fast constant-time comparisons.