How to Add an Element to an Array Only if it Doesn't Exist in JavaScript
When managing a list of items, you often need to add a new element while ensuring there are no duplicates. This creates a "unique set" of items in your array. Instead of adding an item blindly and then de-duplicating the array, it's far more efficient to check for the item's existence before you add it.
This guide will teach you the modern and most effective methods for this task. You will learn how to use Array.prototype.includes() for simple primitive values and the more powerful Array.prototype.some() for arrays of objects.
Goal: Adding a Unique Element
The objective is to push a new element into an array, but only if an identical element is not already present.
Input Array: ['apple', 'banana']
- Add 'cherry': The array should become
['apple', 'banana', 'cherry']. - Add 'apple': The array should remain unchanged because "apple" already exists.
Solution 1 (Recommended for Primitives): Using Array.prototype.includes()
For arrays of primitive values (like strings, numbers, or booleans), the includes() method is the cleanest, most readable, and most direct way to check for an element's existence.
The logic:
- Use the
includes()method to check if the array already contains the element. It returnstrueorfalse. - Use an
ifstatement with a logical NOT (!) operator to runpush()only if the result isfalse.
Solution:
const fruits = ['apple', 'banana', 'cherry'];
const newFruit = 'banana';
// The includes() method returns true, so the condition is false.
if (!fruits.includes(newFruit)) {
fruits.push(newFruit);
}
console.log(fruits); // Output: ['apple', 'banana', 'cherry'] (unchanged)
const anotherFruit = 'date';
// The includes() method returns false, so the condition is true.
if (!fruits.includes(anotherFruit)) {
fruits.push(anotherFruit);
}
console.log(fruits); // Output: ['apple', 'banana', 'cherry', 'date']
Output:
[ 'apple', 'banana', 'cherry' ]
[ 'apple', 'banana', 'cherry', 'date' ]
Solution 2 (Recommended for Objects): Using Array.prototype.some() or findIndex()
The includes() method does not work well for arrays of objects because it checks for object identity (whether they are the same object in memory), not for structural equality (whether they have the same property values).
The problem:
const users = [{ id: 1, name: 'John' }];
const newUser = { id: 1, name: 'John' };
// This is FALSE because they are two different objects in memory.
console.log(users.includes(newUser)); // Output: false
Solution with some()
The some() method is the perfect tool for this. It checks if at least one element in the array passes a test you provide.
const users = [{ id: 1, name: 'John' }];
const newUser = { id: 2, name: 'Jane' };
// Check if any object in the array has the same 'id'
const userExists = users.some(user => user.id === newUser.id);
if (!userExists) {
users.push(newUser);
}
console.log(users); // Output: [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' } ]
Output:
[ { id: 1, name: 'John' }, { id: 2, name: 'Jane' } ]
Solution with findIndex()
findIndex() is a similar and equally valid approach. It returns the index of the first matching element, or -1 if no match is found.
const users = [{ id: 1, name: 'John' }];
const newUser = { id: 1, name: 'John' };
const index = users.findIndex(user => user.id === newUser.id);
// The index will be 0, not -1, so the condition is false.
if (index === -1) {
users.push(newUser);
}
console.log(users); // Output: [ { id: 1, name: 'John' } ] (unchanged)
Output:
[ { id: 1, name: 'John' } ]
Both some() and findIndex() are excellent choices. some() can be slightly more readable as its intent is clearer (does an item exist?).
Alternative Methods (indexOf)
The indexOf() method is an older alternative to includes() for primitive values. It returns the index of the element, or -1 if it's not found.
const fruits = ['apple', 'banana'];
const newFruit = 'apple';
if (fruits.indexOf(newFruit) === -1) {
fruits.push(newFruit);
}
This works, but includes() is generally preferred because its boolean return value (true/false) is more direct and readable for an existence check.
Practical Example: A "Tagging" System
This script allows a user to add unique tags to a list. It correctly handles both primitive values and prevents duplicates.
const tags = ['javascript', 'webdev'];
function addTag(newTag) {
console.log(`Attempting to add tag: "${newTag}"`);
// Normalize the tag to lowercase and trim whitespace
const cleanedTag = newTag.toLowerCase().trim();
if (cleanedTag && !tags.includes(cleanedTag)) {
tags.push(cleanedTag);
console.log('Tag added.');
} else {
console.log('Tag already exists or is empty. Not added.');
}
console.log('Current tags:', tags);
console.log('---');
}
addTag('react'); // Is added
addTag(' javascript '); // Already exists (after cleaning)
addTag('css'); // Is added
Conclusion
Adding a unique element to an array requires a simple pre-check to maintain a duplicate-free list.
- For arrays of primitives (strings, numbers), the
Array.prototype.includes()method is the recommended best practice for its clarity and directness. - For arrays of objects, you must check a unique property. The
Array.prototype.some()method is the most readable and efficient tool for this.findIndex()is also an excellent alternative. - Avoid using
indexOf()for simple existence checks, asincludes()is more modern and its intent is clearer.