javascriptfor-loopreturn-valuerest-parameters

Why does this code work in certain cases and in others it doesn't?


const removeFromArray = function (array,...numbersToRemove) {
    for(let i = 0; i < array.length; i++) {
        for(let a = 0; a < numbersToRemove.length; a++) {
            if(array[i] === numbersToRemove[a]) {
                const index = array.indexOf(numbersToRemove[a]);
                array.splice(index, 1);
            }
        }
        }
        return array; 
    };

console.log(removeFromArray([1, 2, 3, 4], 2, 3));

This code works fine. However if you write console.log(removeFromArray([1, 2, 3, 4], 3, 2)); instead, it stops working. Simply because the 3 and the 2 are inverted. Why?

I believe it's because it loops from 0 to x and so if it's at loop nr. 3 then you give it a 2, it won't loop from 0 again it will continue looping from 3+ until the loop ends, right? So... how can I fix this?

PS. Please don't use arrow functions since I'm not there yet in my study path


Solution

  • The problem is that splice() changes the array you are iterating over, which screws up your current position in the array if the removed position comes before the one your are at. If you invert the loops and go overt the numbersToRemove in the outer loop, it should work.

    Overall, you can make it much simpler though by removing the outer loop altogether. The way it is, you are searching through array again anyway:

    const removeFromArray = function(array, ...numbersToRemove) {
      for (let a = 0; a < numbersToRemove.length; a++) {
        for (let i = 0; i < array.length; i++) {
          if (array[i] === numbersToRemove[a]) {
            array.splice(i, 1);
          }
        }
      }
      return array;
    };
    
    console.log(removeFromArray([1, 2, 3, 4], 3, 2));

    Or just:

    const removeFromArray = (arr, ...numbersToRemove) => arr.filter(e => !numbersToRemove.includes(e))
    console.log(removeFromArray([1, 2, 3, 4], 3, 2));