简体   繁体   中英

A better way to remove an item the index is unknown from the array in JavaScript

I have an array that has zeroes in random indexes. The indexes for given different arrays are unknown. I used the following for loop to find and remove the zeros, so the resulting array is the same one without the zeros.

for (let i=0; i< arr.length; i++){
    if(arr[i] === 0){
      itemIndex = arr.indexOf(arr[i]);
      arr.splice(itemIndex, 1); //removes the zero at the index
      i = 0; //resets the i to zero so that every item in the array is searched even after it is altered.
    }
  }

As you can see, it resets the "i" to zero so that I can iterate through the array again because it will be altered and indexes of the zeroes will change. I am wondering if there is a better way to do this? I have a feeling that this could be coded better.

You only need to decrement i by 1. Also, there is no need to use indexOf when you already have the index.

for (let i=0; i< arr.length; i++){
    if(arr[i] === 0){
      arr.splice(i, 1); //removes the zero at the index
      i--;
    }
  }

Looping backwards also solves the issue without additional counter manipulation, as only elements that have already been checked will be shifted.

Of course, it is much easier to use Array#filter instead.

arr = arr.filter(x => x !== 0);

Here's a couple options you can take here...

  1. Retain your for loop: instead of i = 0 , you could decrement i instead (ie replace i = 0 with i-- )
  2. Replace the loop with a filter: arr = arr.filter(element => element !== 0)

Both will modify the array in place, like you wanted. The second option will not work if arr was initialized as a constant. If that's the case, you'll have to go with option 1, or assign the filter result to a new array and use that after the filter in place of your original array.

Second option is a bit cleaner, but the first is a small change to your existing code to have it to work as you expected.

You could count down (ie for (let i=arr.length-1; i>=0; i--) so the indices of the elements you haven't checked yet won't change.

let result = arr.filter(e => e!==0)

Or if you want to stick with the for loop implementation:

what about populating a new array instead of mutating the one you are looping over:

let result = []

for(let e of arr) {
    if(e!==0) result.push(e)
}

This is my preferred method of removing items from an array like this.

const newArray = array.filter(item => ele !== 0) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM