JavaScript
arrays
unique function
duplicate
programming

unique for arrays in JavaScript

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

JavaScript does not have a built-in Array.prototype.unique() method, but creating a unique array is still easy and common. The best approach depends on what the array contains, because primitives and objects need different strategies.

The Modern Default: Set

For arrays of primitive values such as numbers, strings, and booleans, Set is the cleanest solution.

javascript
1const values = [1, 2, 2, 3, 4, 4, 5];
2const uniqueValues = [...new Set(values)];
3
4console.log(uniqueValues); // [1, 2, 3, 4, 5]

This works because Set stores only unique values and preserves insertion order.

You can also write it with Array.from:

javascript
const uniqueValues = Array.from(new Set(values));

The result is the same.

A Reusable unique Helper

If you want a function you can call throughout your codebase:

javascript
1function unique(array) {
2  return [...new Set(array)];
3}
4
5console.log(unique(["a", "b", "a", "c"]));

This is the most idiomatic helper for primitive arrays in modern JavaScript.

Older Alternative: filter Plus indexOf

Before Set became the obvious answer, a common pattern was:

javascript
1const values = [1, 2, 2, 3, 4, 4, 5];
2
3const uniqueValues = values.filter((value, index, array) => {
4  return array.indexOf(value) === index;
5});
6
7console.log(uniqueValues);

This still works, but it is more verbose and usually slower on larger arrays because indexOf performs repeated searches.

Objects Need a Different Strategy

Set removes duplicates by reference for objects, not by deep content. That means this array still contains two separate objects:

javascript
1const users = [
2  { id: 1, name: "Ada" },
3  { id: 1, name: "Ada" }
4];
5
6console.log([...new Set(users)].length); // 2

If your objects have a natural unique key, use a Map keyed by that property:

javascript
1const users = [
2  { id: 1, name: "Ada" },
3  { id: 2, name: "Linus" },
4  { id: 1, name: "Ada Lovelace" }
5];
6
7const uniqueUsers = [...new Map(users.map(user => [user.id, user])).values()];
8
9console.log(uniqueUsers);

That keeps the last object for each id. If you want the first one instead, reverse the choice or build the map conditionally.

Preserving the First Match

Here is a helper that keeps the first object for a given key:

javascript
1function uniqueBy(array, keyFn) {
2  const seen = new Set();
3
4  return array.filter(item => {
5    const key = keyFn(item);
6    if (seen.has(key)) {
7      return false;
8    }
9
10    seen.add(key);
11    return true;
12  });
13}
14
15const users = [
16  { id: 1, name: "Ada" },
17  { id: 2, name: "Linus" },
18  { id: 1, name: "Ada Lovelace" }
19];
20
21console.log(uniqueBy(users, user => user.id));

This is often the most practical "unique array" utility in application code.

Equality Details Matter

For primitives, Set handles values the way modern JavaScript collections define sameness. That gives intuitive results for normal use:

  • duplicate strings collapse
  • duplicate numbers collapse
  • duplicate booleans collapse

For objects and arrays, equality is by reference. Two separate objects with the same fields are still different values unless you create your own keying rule.

Sorting Is Separate from Deduplication

Uniqueness and sorting are different operations. If you need both, do them deliberately:

javascript
1const values = [3, 1, 2, 3, 2, 1];
2const uniqueSorted = [...new Set(values)].sort((a, b) => a - b);
3
4console.log(uniqueSorted); // [1, 2, 3]

Do not assume deduplication automatically sorts the data.

Common Pitfalls

The biggest pitfall is using Set on objects and expecting deep equality. Set only knows whether two object references are the same object.

Another pitfall is reaching for the older filter and indexOf pattern in modern code when Set is clearer and usually more efficient.

A third pitfall is forgetting that deduplication preserves insertion order rather than applying any custom ordering logic.

Finally, if the array can contain mixed types, be explicit about what "duplicate" should mean before choosing a helper.

Summary

  • For primitive arrays, [...]new Set(array) is the cleanest unique pattern
  • 'Array.from(new Set(array)) is an equivalent alternative'
  • Objects need a key-based strategy such as Map or a custom uniqueBy helper
  • Deduplication does not imply sorting
  • The right unique solution depends on how equality should be defined for the values in the array

Course illustration
Course illustration

All Rights Reserved.