DEV Community

Discussion on: Removing an Element in an Array In-Place

Collapse
 
merri profile image
Vesa Piittinen • Edited

Here are a couple of solutions that avoid the good old for loop just for the sake of avoiding it:

function removeItemInPlace(array, item) {
  let i
  while ((i = array.indexOf(item, i)) > -1) {
    array.splice(i, 1)
  }
  return array.length
}

I also named the function and variables differently, because element is easy to confuse with concepts like DOM elements or React elements, so I often prefer talking about array items instead.

You can optimize the above for a more straightforward readability:

function removeItemInPlace(array, item) {
  let i = array.indexOf(item)
  if (i === -1) return array.length
  do {
    array.splice(i, 1)
    i = array.indexOf(item, i)
  } while (i >-1)
  return array.length
}

The above code is structured so that if you ever decide to remove the mutation in place (which is often favored these days) and instead of length output the resulting array, you can have an optimization that simply returns the original array if no changes were done. It also makes use of do while loops which seem to be used quite rarely.

We can also use regular for loops in a slightly more unusual way if we remove the requirement for future immutability:

function removeItemInPlace(array, item) {
  for (let i = array.indexOf(item); i > -1; i = array.indexOf(item, i)) {
    array.splice(i, 1)
  }
  return array.length
}

Then finally the functionalish way to do this:

function removeItemInPlace(array, item) {
  return array.reduceRight((array, arrayItem, index) => {
    if (item === arrayItem) array.splice(index, 1)
    return array
  }, array).length
}

Although you'll probably scare those hipster coders who have put their faith on immutability! :D It is a bit weird how they want to waste so much processing power and effort to creating new arrays on every iteration of a loop just to "be sure" they don't do mutation. Anyway, I know I still would get super mega awesome bonus points for using reduceRight since you really don't see that one being used in the wild.