skip to Main Content

I’ve been working with JavaScript arrays recently, and I’ve come across a situation where I need to remove certain items from an array. Here’s an example of what I mean:

let myArray = ['apple', 'banana', 'cherry', 'date', 'elderberry'];

Let’s say I need to remove the ‘banana’ and ‘date’ from this array. What would be the most efficient way to achieve this? I would ideally like the solution to be scalable, in case I need to remove more items in the future.

I know that I could use a loop to iterate through the array and splice the array when the item is found, like so:

for (let i = 0; i < myArray.length; i++) {
    if (myArray[i] === 'banana' || myArray[i] === 'date') {
        myArray.splice(i, 1);
        i--;
    }
}

However, I’m wondering if there’s a better, more JavaScript-esque way to accomplish this task. Also, I’ve heard that using splice within a loop can lead to issues due to the changing indices.

Any assistance you could provide would be greatly appreciated.

I am expecting better results.

2

Answers


  1. Here’s a more efficient and concise way to remove specific items from a JavaScript array without using splice:

    let myArray = ['apple', 'banana', 'cherry', 'date', 'elderberry'];
    let itemsToRemove = new Set(['banana', 'date']);
    
    myArray = myArray.filter(item => !itemsToRemove.has(item));
    

    In this solution, we use the filter method along with a Set to efficiently remove specific items from the array. The Set data structure allows for faster lookup, making the solution scalable and efficient.

    Here’s how it works:

    Create a Set named itemsToRemove containing the items you want to remove (‘banana’ and ‘date’ in this case).

    Use the filter method on the myArray to create a new array that only includes items that are not present in the itemsToRemove set.

    The result will be myArray with ‘banana’ and ‘date’ removed:

    ['apple', 'cherry', 'elderberry']
    

    Using this approach, you can efficiently remove any number of specific items from the array without having to deal with changing indices and with better performance compared to using a splice inside a loop.

    Login or Signup to reply.
  2. I would not worry about performance and just go for Array.prototype.filter() as:

    • It’s the simplest and easier to read/understand implementation.
    • Works with multiple occurrences of the same item.
    • Seems to be the fastest anyway (this might change depending on the shape and size of you data and browser).

    Anyway, here’s a playground with different option for you to take a look and experiment:

    function measure(name, callback, runs = 100000) {
      const t0 = performance.now();
      
      for (let i = 0; i <= runs; ++i) {
        callback()
      }
      
      const t1 = performance.now() - t0;
      
      console.log(name, t1, 'ms')
    }
    
    const myArray = ['apple', 'banana', 'cherry', 'date', 'elderberry'];
    const myElementsToRemove = ['banana', 'date'];
    
    function removeMultipleWithSplice(arr, elementsToRemove) {
      const newArr = arr.slice(0)
      
      elementsToRemove.forEach((elementToRemove) => {
        // This won't work for multiple ocurrences of the same item:
        const index = newArr.indexOf(elementToRemove)
        
        if (index >= 0) {
          newArr.splice(index, 1);
        }
      })
      
      return newArr;
    }
    
    function removeMultipleWithFilter(arr, elementsToRemove) {
      return arr.filter((element) => !elementsToRemove.includes(element))
    }
    
    function removeMultipleWithForAndPush(arr, elementsToRemove) {
      const newArr = []
      
      for (const element of arr) {
        if (!elementsToRemove.includes(element)) newArr.push(element)
      }
      
      return newArr;
    }
    
    // console.log(removeMultipleWithSplice(myArray, myElementsToRemove))
    // console.log(removeMultipleWithFilter(myArray, myElementsToRemove))
    // console.log(removeMultipleWithForAndPush(myArray, myElementsToRemove))
    
    measure('removeMultipleWithSplice', () => {
      removeMultipleWithSplice(myArray, myElementsToRemove)
    })
    
    measure('removeMultipleWithFilter', () => {
      removeMultipleWithFilter(myArray, myElementsToRemove)
    })
    
    measure('removeMultipleWithForAndPush', () => {
      removeMultipleWithForAndPush(myArray, myElementsToRemove)
    })
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search