A javascript array unique (or js unique array) result removes duplicate entries while usually keeping first-seen order. The standard one-liner is [...new Set(arr)]. For javascript array distinct / distinct array javascript with objects, you either rely on reference identity in a Set, or use a Map keyed by a field. For background on Set itself, see HashSet in JavaScript (Set); for removing a known element from a list (different problem), see remove element from array in JavaScript.
Tested on: all examples in this tutorial were run with Node.js v20.18.2, and the output shown below each snippet is its exact console output.
Quick reference
Use this table for array unique javascript approaches: default primitive dedupe, NaN-safe behavior, object keys, and typical cost.
| Approach | Typical complexity | Notes |
|---|---|---|
[...new Set(arr)] |
O(n) | Best default for primitives; handles NaN once |
filter + indexOf |
O(n²) | Fails for NaN as written |
reduce + includes |
O(n²) | Clear, fine for small arrays |
Map by key |
O(n) | Unique by property, not by reference |
Set + spread — array unique javascript
Set removes duplicates using SameValueZero equality and preserves insertion order when iterated.
const arr = [1, 2, 2, 3, 3, 4, 5];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr);[ 1, 2, 3, 4, 5 ]Same result with Array.from (handy if you prefer a factory style):
console.log(Array.from(new Set([1, 2, 2])));[ 1, 2 ]The spread operator expands the Set iterator into a new array; see also creating numeric ranges as arrays when building inputs.
filter + indexOf — keep first occurrence (js array unique)
Keep the first index where indexOf still points at the current element; later duplicates fail the equality check.
const arr = [45, 67, 67, 89, 67, 69];
const uniqueArr = arr.filter((element, index, self) => {
return index === self.indexOf(element);
});
console.log(uniqueArr);[ 45, 67, 89, 69 ]Caveat: this pattern does not work for NaN, because indexOf(NaN) is always -1:
console.log([...new Set([NaN, NaN, NaN])]);
const a = [NaN, NaN];
console.log(a.filter((e, i, s) => i === s.indexOf(e)));[ NaN ]
[]For NaN, prefer Set or something like findIndex((x) => Object.is(x, e)).
reduce + includes
Build an accumulator array and skip values already present—simple to read but includes scans the accumulator each time.
const arr = [45, 67, 67, 89, 34, 34, 69];
const uniqueArr = arr.reduce((acc, each) => {
if (!acc.includes(each)) {
acc.push(each);
}
return acc;
}, []);
console.log(uniqueArr);[ 45, 67, 89, 34, 69 ]Still O(n²) worst case because includes scans the accumulator.
for loop + includes
Imperative style matches the reduce pattern: push only when the running list does not already contain the value.
const myArray = [1, 2, 3, 2, 4, 1, 5];
const uniqueArray = [];
for (let i = 0; i < myArray.length; i++) {
if (!uniqueArray.includes(myArray[i])) {
uniqueArray.push(myArray[i]);
}
}
console.log(uniqueArray);[ 1, 2, 3, 4, 5 ]See JavaScript for loop with index for loop basics.
Distinct by a key — javascript array distinct for objects
Set treats object literals as distinct references. To collapse by id, use a Map (last occurrence wins here):
const objs = [{ id: 1 }, { id: 1 }, { id: 2 }];
console.log([...new Map(objs.map((o) => [o.id, o])).values()]);[ { id: 1 }, { id: 2 } ]Summary
- Prefer
[...new Set(arr)]orArray.from(new Set(arr))for primitive dedupe with first-seen order. - Avoid
indexOf-based uniqueness for values that includeNaN;Sethandles SameValueZero correctly. reduce/for+includesis readable but quadratic; fine for small inputs.- For objects, dedupe by a stable key with
Map, not reference identity in aSet.
References
MDN references for Set, Map, and array iteration helpers used in javascript unique array recipes.
