Guide · Published September 2026
“Difference between two arrays” usually means one of two things: items only in the first array, or a full set-style comparison. Both are short in modern JavaScript.
Items only in array A
const onlyInA = a.filter(item => !b.includes(item));
This keeps every item from a that doesn’t show up anywhere in b. Swap a and b to get the reverse direction.
Faster for large arrays: use a Set
includes() re-scans the whole array on every call, so nesting it inside filter() is quadratic — fine for small arrays, slow for large ones. Fix it by converting the lookup array to a Set first:
const bSet = new Set(b); const onlyInA = a.filter(item => !bSet.has(item));
Removing duplicates from a single array
const unique = [...new Set(array)];
Spreading a Set back into an array removes duplicates while keeping the original insertion order, since JavaScript Sets iterate in the order items were added.
Case-insensitive comparison
Neither includes() nor Setnormalize case, so “Apple” and “apple” count as different values by default. Normalize before comparing if that matters:
const bSet = new Set(b.map(x => x.toLowerCase())); const onlyInA = a.filter(x => !bSet.has(x.toLowerCase()));
The intersection and union, for completeness
- Intersection:
a.filter(x => bSet.has(x)) - Union:
[...new Set([...a, ...b])]
Comparing arrays of objects
Everything above works directly for arrays of primitives (strings, numbers). includes() and Set both compare objects by reference, not by value, so two different object instances with identical properties are never treated as equal, even if they look the same when logged. To compare by a specific property instead:
const bIds = new Set(b.map(x => x.id)); const onlyInA = a.filter(x => !bIds.has(x.id));
This compares by id (or whichever field identifies a matching record) instead of comparing whole objects.
Why the naive nested-includes version is slow
a.filter(item => !b.includes(item)) without converting b to a Set is O(n × m): for every item in a, includes() scans the entirety of b. For two arrays of a few hundred items each, that’s barely noticeable. For two arrays of tens of thousands of items, it can take seconds instead of milliseconds — converting b to a Set first turns each lookup from O(m) into roughly O(1), which is the single biggest performance fix available here.
Checking your result
A quick sanity check after any of these operations: onlyInA.length should never exceed a.length, and for a correct intersection, intersection.length should never exceed the smaller of the two input arrays. If either check fails, something upstream (usually inconsistent casing or whitespace) is preventing values that should match from matching.
TypeScript note
Everything above is plain JavaScript and works unchanged in TypeScript, but typing Set<T> and the filter callbacks explicitly (a: T[], b: T[]) catches a common mistake early: comparing arrays of two different types, where includes() would silently always return false instead of raising an error. The compiler catches the mismatch instead of leaving it as a confusing runtime bug.
Generic helper functions typed once as <T,> are worth writing if you find yourself repeating this pattern across a codebase.
Same idea in other languages
For a Python list, see removing duplicates from a Python list. For a database table, see removing duplicate rows in SQL.
No code required
For a one-off comparison of two pasted lists, the list comparison tool computes all four set operations at once without writing any JavaScript.
Skip the code for a one-off comparison.
Open the comparison toolFrequently asked questions
How do I find items in one array but not another in JavaScript?
a.filter(item => !b.includes(item)) returns every item in array a that doesn't appear in array b.
Why is Set faster than includes() for large arrays?
Array.includes() scans the whole array each time (O(n) per check), while Set.has() is close to O(1) — for large arrays, converting to a Set first turns an O(n*m) comparison into roughly O(n+m).
How do I remove duplicates from a single JavaScript array?
[...new Set(array)] removes duplicates while preserving the first occurrence's order, since JavaScript Sets iterate in insertion order.
How do I get the symmetric difference of two arrays?
Combine both one-directional differences: [...a.filter(x => !b.includes(x)), ...b.filter(x => !a.includes(x))] gives everything that doesn't match on either side.