Removing Elements from JavaScript Arrays
The JavaScript standard library is notoriously small. In fact, it is so small that the Array
prototype doesn't even define a method for removing a specific element from an array. Because there's no such built-in method, developers have to create their own version if they want to remove a specific array element.
#Approach #1: indexOf()
and splice()
A common approach is to combine the indexOf()
and splice()
methods like this:
function remove(array, element) {
const index = array.indexOf(element);
array.splice(index, 1);
}
First, the index of the element in question is determined via indexOf()
. Second, splice()
is used to remove the array element at that index. We only want to remove a single value, so we pass 1
as the second argument to splice
, which specifies the delete count.
However, our above remove()
function is flawed, as a simple example shows:
const vowels = ["a", "e", "i", "o", "u", "x"];
vowels.toString(); // "a,e,i,o,u,x"
// Let's remove "x" since it's not a vowel.
remove(vowels, "x");
vowels.toString(); // "a,e,i,o,u"
// What happens if we remove "x" again? Oops!
remove(vowels, "x");
vowels.toString(); // "a,e,i,o"
The remove()
function removes the last array element if the element to remove doesn't occur within the array. In that case, indexOf()
returns the sentinel value -1
. That value is passed to splice()
, which starts to count from the end of the array when it sees a negative index. -1
is the index of the last array element — not what was intended here.
Here's a correct version of the remove()
function. The fix is to call splice()
if and only if indexOf()
didn't return -1
:
function remove(array, element) {
const index = array.indexOf(element);
if (index !== -1) {
array.splice(index, 1);
}
}
Look before you leap! Always check your indexOf()
return values.
#Approach #2: filter()
Removing an element from a given array is a mutating operation. The remove()
function changes the array that was passed to it, which is typically not what the caller would expect.
A better approach would be to implement a non-mutating element removal. Instead of directly modifying the input array, the remove()
function could return a new array that contains all elements except the specified one:
function remove(array, element) {
return array.filter(el => el !== element);
}
const vowelsAndX = ["a", "e", "i", "o", "u", "x"];
const vowels = remove(vowelsAndX, "x");
vowels.toString(); // "a,e,i,o,u"
Note that this non-mutating version of remove()
works a little differently than its mutating sibling. Instead of removing only the first occurrence of the given element from the new array, we now return a new array that doesn't contain any occurrence of the given element.