How to Remove an Item at a Specific Index in JavaScript? What About Multiple Items?

Time to cut some items out of an array!
Photo by Markus Winkler / Unsplash

The best solution for removing an item at a specified position (index) in an array will depend on your use-case. Here’s some of the questions we’ll explore and give a unique answer for:

  • Does the array consists of primitives such as Numbers or Strings or is are the elements Objects?
  • Do you already know the index or is there a condition based on which you need to remove item(s)?
  • Are we removing exclusively one item or are we removing more?
  • Is the array large? (Do you need it to be efficient?)

Removing an Item at a Specific Index

The most common use case is when you already know the index you want to remove. In this case it doesn’t matter what the array consists of and the solution is going to be as efficient as it could be with Array.splice.

const arr = ['Apple', 'Orange', 'Banana'];
arr.splice(1, 1);
console.log(arr);
// => Array [ "Apple", "Banana" ]

The first parameter is the index at which you wish to start removing items and the second is how many items you want to remove. If you just want to remove one, then the second parameter will always be 1.

You can also catch the item that was removed as a return value:

const arr = ['Apple', 'Orange', 'Banana'];
const removedItems = arr.splice(1, 1);
console.log(removedItems);
// => Array [ "Orange" ]

More experienced developers know that there’s something dirty happening with splice – the array is being mutated which is not a good idea if the array was provided as a parameter to your function. (Never mutate your function’s arguments!)

To avoid that we can use Array.slice which returns a slice of the array between the given indexes and does not mutate the original array. So, we can do this:

const animals = [ 'cat', 'dog', 'bird', 'snake', 'camel', 'ant' ];
const removeAt = (arr, index) => {
  return [...arr.slice(0, index), ...arr.slice(index + 1, arr.length)];
};
const result = removeAt(animals, 2); // remove “bird” at index 2
console.log(result);
// => Array [ "cat", "dog", "snake", "camel", "ant" ]

In theory, this method is going to be slower and more memory intense. It might be more efficient for you to copy the array and use the splice method to mutate the copy instead.

But do not use hypothethical strawman arguments to reason about which of those methods you should use. Do an actual benchmark that fits your use case. Don’t trust everything you see on the Internet! :)

Removing an Item at an Unknown Index

Let’s say you need to remove a single unique item, but don’t know the index. You can use the Array.filter method. For example:

const animals = [ 'cat', 'dog', 'bird', 'snake', 'camel', 'ant' ];
const newArray = animals.filter(animal => animal !== 'snake'); // remove “snake”
console.log(newArray);
// => Array [ "cat", "dog", "bird", "camel", "ant" ]

We can also make it work with Objects:

const animals = [ { name: 'cat' }, { name: 'dog' }, { name: 'snake' } ];
const newArray = animals.filter(animal => animal.name !== 'snake');
console.log(newArray);
// => Array [ { name: "cat" }, { name: "dog" } ]

But what if the item is not unique? What if there’s multiple “snake” items and you just want to remove the first one? Then you can use Array.findIndex to first find the index and then either use the splice or slice method from before.

Example:

const animals = ['dog', 'snake', 'cat', 'bird', 'snake'];
const firstIndex = animals.findIndex(animal => animal === 'snake'); // => 1
// or with objects:
const animals = [{ name: 'dog' }, { name: 'snake' }, { name: 'cat' }];
const firstIndex = animals.findIndex(animal => animal.name === 'snake'); // => 1

If you are working with primitives such as a String, you can also use the shorter Array.indexOf method:

const animals = ['dog', 'snake', 'cat', 'bird', 'snake'];
const firstIndex = animals.indexOf('snake'); // => 1

This does not work with objects. Also, bear in mind that this method returns -1 if it does not find any match.

Removing Multiple Items at Specific Indexes

This is probably the trickiest one. Let’s say you know you have to remove items at index 0 and 2. You might go the naïve route and call our removeAt or the splice method twice, but that would be wrong. As soon as you remove the item at index 0, the array has changed. What was once on index position 2 is now on index position 1!

The simple solution for this is to sort the indexes you wish to remove and execute them in reverse order.

const removeMultiple = (arr, indexes) => {
  // sort indexes in reverse order
  const sorted = indexes.sort((a, b) => b - a); 
  for (let index of sorted) {
    arr.splice(index, 1); // or use a different deletion method
  }
}

// ...somewhere else
const indexesToRemove = [3, 0, 1, 2];
const arr = ['item_0', 'item_1', 'item_2', 'item_3', 'item_4'];
removeMultiple(arr, indexesToRemove);
console.log(arr);
// => Array [ "item_4" ];

But there’s a solution that has way less headache if you arrays are small and the performance impact is minimal – you can use Array.filter again! The second argument of the callback function in Array.filter is the original index. So you can do this in one go:

const indexesToRemove = [3, 0, 1, 2];
const arr = ['item_0', 'item_1', 'item_2', 'item_3', 'item_4'];
const newArray = arr.filter((value, index) => 
  indexesToRemove.indexOf(index) === -1
);
console.log(newArray);
// => Array [ "item_4" ];

Removing Multiple Items at Unknown Indexes

Filter is going to be your bread and butter again. You’ll want to specify your condition as part of the callback function and filter out everything that doesn’t fit.

const animals = ['dog', 'snake', 'ant', 'snake', 'cat', 'bird', 'snake'];
const newArray = animals.filter((animal) => animal !== 'snake'); // remove all snakes
console.log(newArray);
// => Array [ "dog", "ant", "cat", "bird" ]

And of course you can do this with Objects as well.

Performance Concerns

Going through an entire array, especially more than once, and creating new copies can impact performance if those arrays are large and you’re application processes a lot of them. By large I mainly mean at least a few thousands of items that are frequently being checked. It’s very hard to come up with a one-fits-all benchmark as there are many parameters to consider.

As always, you should examine your own use case, the type of data you’re using, and consider how large it could get – then create benchmark to decide which of these methods works best for you.

Filip Danic

Filip Danic

Software Development Manager at Amazon and recovering JavaScript enthusiast. Sharing my experience and insights with the broader tech community via this blog!
The Netherlands