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: Node.js v20.18.2. A short note after each snippet describes what you should see in the console.
Quick reference
Set is the default primitive deduper (NaN-safe, amortized O(n)); reach for Map when uniqueness is defined by a field, not object identity.
| 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);You should see one line like: [ 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])));You should see one line like: [ 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);You should see one line like: [ 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)));You should see 2 lines: [ NaN ], then [].
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);You should see one line like: [ 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);You should see one line like: [ 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()]);You should see one line like: [ { id: 1 }, { id: 2 } ].
Summary
[...new Set(arr)] covers most “unique primitives” tickets; indexOf filters fail on NaN, and objects need Map keyed by something stable—not reference equality in a Set unless that is what you mean.
- 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.
Frequently Asked Questions
What is the easiest way to get a javascript array unique list?
Spread a Set: const unique = [...new Set(arr)]. Set removes duplicates using SameValueZero equality and preserves insertion order when you iterate it.
js array unique while keeping the first occurrence of each value?
Set iteration follows first insertion order, so [...new Set(arr)] keeps the first time each value appeared.
Why does my filter with indexOf fail for NaN for javascript unique array?
Array.prototype.indexOf uses SameValue and cannot find NaN. indexOf(NaN) is always -1, so index === indexOf(e) drops every NaN. Use a Set, or findIndex with Object.is.
How do I get array distinct javascript behavior for objects by an id field?
Use a Map keyed by the field, then take .values(). Duplicate keys overwrite earlier entries—decide if you want first or last wins.
Array unique javascript with Set—does it deep-duplicate objects?
No. Set stores references; two different object literals are always distinct. To treat objects as equal by a key, use Map or a serialized key strategy.
Is filter plus indexOf slower than Set for large arrays?
Usually yes. filter with indexOf is roughly O(n squared) because indexOf scans up to i each time. Set-based dedupe is amortized O(n).
