, ,

Removing Duplicates in JavaScript: Sets vs. Filter

Posted by

Two common patterns in JavaScript to deduplicate arrays — and when to use each.

Two common patterns in JavaScript to deduplicate arrays — and when to use each.

Introduction

Every developer eventually faces this:

const arr = [1, 2, 2, 3, 4, 4, 5];

👉 How do you get:

[1, 2, 3, 4, 5]

There are dozens of tricks floating around — Set, filter, reduce, Lodash’s uniq. But the two most common in vanilla JavaScript are:

  1. Using Set
  2. Using Array.prototype.filter

They both work, but they aren’t interchangeable. This guide will break down both approaches with clear code, pros/cons, performance notes, and real-world cases.


1) Using Set (The Modern Default)

Set is a built-in collection type introduced in ES6. It stores only unique values.

Example:

const arr = [1, 2, 2, 3, 4, 4, 5];
const unique = [...new Set(arr)];

  • Convert array → Set (removes duplicates).
  • Spread back into a new array.

👉 This is usually the fastest and simplest way.


2) Using filter (The Classic Way)

Before ES6, devs used filter with indexOf or findIndex.

Example:

const arr = [1, 2, 2, 3, 4, 4, 5];
const unique = arr.filter((item, index) => arr.indexOf(item) === index);

console.log(unique); // [1, 2, 3, 4, 5]

How it works:

  • For each element, check if its first index matches the current index.
  • If yes → it’s the first occurrence → keep it.
  • If no → it’s a duplicate → skip it.

3) Comparing Sets vs. Filter

Syntax Simplicity

  • Set: One-liner, very clean.
  • Filter: Slightly longer and less readable.

Performance

For large arrays:

  • Set: Generally faster — O(n) with hashing.
  • Filter: Slower — indexOf is O(n), so worst-case is O(n²).

👉 With 100k+ items, Set will usually win big.


Data Types

  • Set preserves uniqueness by strict equality (===).
  • Filter can be customized:
// Deduplicate case-insensitively
const arr = ["a", "A", "b", "B"];
const unique = arr.filter(
(item, index, self) => self.findIndex(x => x.toLowerCase() === item.toLowerCase()) === index
);

console.log(unique); // ["a", "b"]

👉 Use filter if you need custom rules for equality.


Order Preservation

Both approaches preserve the first occurrence order.

const arr = [3, 2, 2, 1];
console.log([...new Set(arr)]);
// [3, 2, 1]

console.log(arr.filter((x, i) => arr.indexOf(x) === i));
// [3, 2, 1]

Handling Objects

const arr = [{ id: 1 }, { id: 1 }, { id: 2 }];

console.log([...new Set(arr)]);
// [{ id: 1 }, { id: 1 }, { id: 2 }] ❌ (different references)

👉 Set sees objects as unique unless they are the same reference.

For objects, you often need filter with custom comparison:

const uniqueById = arr.filter(
(obj, index, self) => index === self.findIndex(o => o.id === obj.id)
);

console.log(uniqueById); // [{ id: 1 }, { id: 2 }]

4) Real-World Use Cases

a) Deduplicating IDs

const ids = [1, 2, 3, 2, 4, 1];
const uniqueIds = [...new Set(ids)];

b) Deduplicating Search Results

const results = [
{ id: 1, name: "Alice" },
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" }
];

const uniqueResults = results.filter(
(item, idx, arr) => idx === arr.findIndex(r => r.id === item.id)
);

c) Deduplicating Case-Insensitive User Input

const tags = ["JS", "js", "JavaScript", "JS"];
const uniqueTags = tags.filter(
(t, i, arr) => arr.findIndex(x => x.toLowerCase() === t.toLowerCase()) === i
);

5) Quick Reference Table


Conclusion

  • Use Set when:
  • You’re deduplicating primitive values.
  • You want the fastest, cleanest solution.
  • You’re working with large arrays.
  • Use filter when:
  • You need custom equality rules (case-insensitive, compare object keys).
  • You’re deduplicating arrays of objects.
  • Readability of explicit logic matters.

Pro tip: In modern codebases, start with Set. Reach for filter only when you need extra control.


Call to Action

Which one do you reach for first — Set or filter?

💬 Share your favorite deduplication trick in the comments.
🔖 Bookmark this as your cheat sheet for array uniqueness.
👩‍💻 Share with a teammate who still writes for loops to remove duplicates.

Leave a Reply

Your email address will not be published. Required fields are marked *