How to Remove Duplicates from Array in JavaScript
Master practical techniques to remove duplicates from an array in JavaScript. Learn Set-based deduplication, order preservation, object-sensitive methods, and performance considerations with step-by-step examples.

By the end of this guide, you’ll be able to remove duplicates from a JavaScript array using several proven methods. We cover primitive arrays with Set, filter-based approaches, and custom deduplication for objects, including preserving order and handling edge cases. You’ll also learn when to choose each technique and how to measure performance in real-world code.
How to Remove Duplicates from Array in JavaScript
In JavaScript, removing duplicates from an array is a common task that appears in data cleaning, UI rendering, and processing pipelines. The keyword for this guide is how to remove duplicates from array in javascript, and you’ll see several practical patterns tailored to primitive values and complex objects. According to JavaScripting, starting with the simplest method is often the best way to build intuition before layering in edge cases. As you read, you’ll notice how the same problem can be solved with different tradeoffs around readability, performance, and compatibility across environments.
First, define what counts as a duplicate for your data. If all items are primitive values (numbers, strings, booleans), a Set-based approach is typically enough. If you’re deduplicating objects, you’ll need a strategy to compare by a key or a custom comparator. This ensures you aren’t treating two distinct objects with identical properties as duplicates unless you intend to.
Primitives with Set: The simplest solution
For arrays of primitive values, the Set constructor offers a straightforward path to deduplication. Sets automatically ignore duplicates, and spreading the Set back into an array preserves the insertion order. This method is widely adopted in codebases because of its clarity and performance characteristics. The canonical pattern for how to remove duplicates from array in javascript is:
const unique = [...new Set(arr)];This approach handles numbers, strings, booleans, and the special case of NaN (where Set treats all NaN values as a single value). If you’re working with primitives only, this method is often the best first choice.
Preserving order and performance considerations
One major advantage of Set-based deduplication is that it preserves the original order of first occurrences. If your data relies on sequence (e.g., a list of IDs read from a file), this is crucial. The time complexity is generally O(n), and memory usage grows with the number of distinct values. When code readability and quick results matter, this method shines. If you anticipate extremely large arrays, you may want to benchmark on the target environment, because memory usage and GC behavior can vary between engines.
A more verbose but explicit way to preserve order and achieve the same result uses Array.from with a Map to track seen values, which also helps you customize what counts as a duplicate when dealing with objects later on.
Alternative: filter and indexOf
If you prefer a more explicit approach that demonstrates the de-duplication logic, you can use Array.filter in combination with indexOf. This method is easy to read but can be less performant on large arrays due to the nested lookup.
const unique = arr.filter((v, i) => arr.indexOf(v) === i);Note that this approach will also work for primitive values, but it has quadratic time complexity in the worst case, which may be prohibitive for very large datasets.
Deduplicating with reduce
Another pattern uses reduce to accumulate a new array of unique values. This approach is flexible and easy to extend for more complex dedup rules, such as deduplicating based on a projection function or a property of objects.
const unique = arr.reduce((acc, curr) => (acc.includes(curr) ? acc : [...acc, curr]), []);While readable, this method creates intermediate arrays on each iteration. For performance-sensitive code, consider preserving order with a Map or using a Set-based approach for primitives and a separate path for objects.
Handling duplicates for objects
Dedupe arrays of objects requires a strategy beyond simple value equality. You must decide which object property (or combination of properties) defines identity. A common tactic is to map each object to a key string and deduplicate by that key. There are several patterns:
- Map objects to a key: const key = obj => obj.id;
- Use a helper to build a unique map: const seen = new Map(); const unique = arr.filter(o => seen.has(o.id) ? false : seen.set(o.id, true));
If you need multi-property identity, build a composite key like ${obj.id}|${obj.type} and deduplicate by that key.
Dedup strategies for large arrays
For large data sets, you’ll care about both speed and memory. The Set-based primitive path is typically fastest, especially when the values are primitives. When dealing with objects, consider a two-pass approach: first, map to a stable key, deduplicate by that key, then reconstruct objects if necessary. In some scenarios, streaming pipelines can deduplicate chunks of data to reduce peak memory usage.
Practical guidance: real-world patterns
In real-world scripts, you’ll often see utility helpers like dedupe that handle both primitives and objects through an optional key extractor function. This promotes code reuse and consistency across modules. A typical utility signature might be: function dedupe(arr, keyFn) { /* ... */ }. When keyFn is provided, you deduplicate by the produced key; otherwise, you deduplicate by value.
Edge cases and input validation
Deduplication functions should gracefully handle non-array inputs, null values, and empty arrays. Validate input early: if (!Array.isArray(arr)) throw new TypeError('Expected an array'); If the array might contain objects, ensure your key function handles undefined values gracefully. Consistent handling of undefined and null helps prevent subtle bugs in downstream processing.
Testing and benchmarking deduplication
Unit tests should cover primitive arrays, arrays with duplicates, empty arrays, and arrays of objects with and without key functions. Simple benchmarks can compare time and memory across methods, but remember that micro-benchmarks can be environment-specific. Prioritize readability and correctness for production code, and reserve micro-optimizations for hot paths.
Integrating deduplication into functions and utilities
As projects grow, you’ll extract dedup logic into utilities or libraries. A robust approach is to export a single dedupe function that accepts an optional key function. Example: export function dedupe(arr, keyFn) { /* ... */ }. This makes your code reusable and helps enforce consistent behavior across modules.
Common pitfalls and best practices
- Don’t assume all elements are primitive; plan for objects as well.
- When deduplicating with sets, remember the insertion order is preserved for primitives but not for complex identity unless you map keys.
- Prefer concise, readable code over clever optimizations unless profiling shows a hot path.
- Document the identity rules clearly so future contributors understand how duplicates are determined.
Tools & Materials
- Code editor(VS Code, Sublime, or any modern editor)
- JavaScript runtime(Node.js or browser console)
- Sample arrays for testing(Include duplicates, mixed types, and objects to test all paths)
- Browser/dev tools(Console access for quick experiments and debugging)
- Documentation references(MDN or official docs for Set, Map, and Array methods)
- Optional libraries(Lodash or similar for alternative approaches (optional))
Steps
Estimated time: 60-90 minutes
- 1
Define the problem
Clarify the array type, what counts as a duplicate, and whether you must preserve the original order. Decide whether you’re deduplicating primitives or objects and identify the output structure.
Tip: Write a small sample array and the expected result before coding. - 2
Choose a deduplication strategy
Select a method based on data type and performance needs. For primitives, Set is usually best; for objects, plan a key extraction strategy.
Tip: Start with the simplest approach (Set) and validate with tests. - 3
Implement Set-based deduplication
Implement the primitive path using `const unique = [...new Set(arr)]` and test with typical inputs.
Tip: Check edge cases like NaN; Set handles NaN as a single value. - 4
Preserve order with alternative patterns
If readability matters, implement an explicit order-preserving method like map-reduce or a keyed Map approach.
Tip: Benchmark against Set for moderate arrays to confirm benefits. - 5
Handle arrays of objects
Introduce a key function to define identity, e.g., `(obj) => obj.id` and deduplicate by that key.
Tip: Avoid mutating original objects; construct new results if needed. - 6
Test with edge cases
Run tests for empty arrays, undefined inputs, mixed types, and null values. Ensure consistent behavior.
Tip: Use assertion libraries or simple `console.assert` checks. - 7
Consider performance
Profile the chosen approach with representative workloads. Large arrays may reveal differences not obvious in small tests.
Tip: Measure time and memory usage in the target runtime. - 8
Package as a utility
If you reuse dedup logic, wrap it as a module or helper with a clear API.
Tip: Document identity rules and default behavior. - 9
Review and refactor
Refactor for readability and maintainability. Remove unnecessary intermediate arrays where possible.
Tip: Add comments describing why a particular method was chosen. - 10
Share learnings with teammates
Publish or document your utility, and collect feedback for improvements.
Tip: Include examples for primitives and objects in the docs. - 11
Apply in real projects
Integrate dedupe utilities in data processing pipelines, UI lists, or API response handling.
Tip: Guard against unexpected input formats from external sources. - 12
Maintain and evolve
Regularly revisit the utility as your data shapes evolve and JavaScript engines improve.
Tip: Keep tests green after refactors and engine updates.
Questions & Answers
What is the simplest way to remove duplicates from an array in JavaScript?
The simplest approach for primitive values is to convert the array to a Set and back: const unique = [...new Set(arr)]. This removes duplicates while preserving order. For objects, you must define identity with a key function.
Use a Set for primitives: const unique = [...new Set(arr)]. For objects, define an identity key to deduplicate.
How can I preserve the original order after deduplication?
Most Set-based solutions preserve insertion order. If you implement a custom dedupe, ensure you push items only when they haven’t appeared before, maintaining the first occurrence order.
Set keeps the original order, but with custom methods, track first appearances to keep order.
What about arrays of objects?
Dedupe by a chosen property (e.g., id) or a composite key. Map each object to its key, deduplicate by the key, then reconstruct objects if needed.
For objects, deduplicate by a key function like id and rebuild results if necessary.
Which method is fastest for large arrays?
In practice, Set-based approaches are fast for primitive arrays. For object arrays, performance depends on key extraction and memory usage; profile your actual data.
Set-based methods are fast for primitives; for objects, test with real data to pick the best approach.
Can I deduplicate a typed array or array-like input?
Typed arrays must be converted to regular arrays for easy deduplication, or you can implement a manual loop that tracks seen values and builds a new typed array.
Convert to a normal array first, then deduplicate, or implement a custom loop for typed arrays.
Is in-place deduplication possible?
In-place deduplication is complicated due to shifting elements. It’s safer to create a new array of uniques and replace the reference where needed.
In-place dedup is tricky; create a new array and swap references when possible.
Watch Video
What to Remember
- Use Set for primitives to deduplicate quickly
- Preserve order when removing duplicates
- Deduplicate objects by a key function
- Benchmark methods for large data
- Validate inputs and edge cases
