My Code should remove all false values but it is not?

Viewed 62

My Code should remove the false values but it is only removing first false value in a given array

const arr = [7, "ate", "", false, 9]



function bouncer(arr) {
  for (let i = 0; i < arr.length; i++) {
    if (!arr[i]) {
      arr.splice(i, 1)
    }
  }
  return arr;
}

console.log(bouncer(arr))

6 Answers

Why don't use filter like:

const arr = [false,7, "ate", "", false, 9];
console.log(arr.filter(el => el !== false));

Reference:

You can't iterate upwards AND shorten your array like this; splice has the side effect of modifying the original array.

Consider what happens in the case [false, false, true]

  1. i = 0, length = 3, arr = [(false), false, true] -> arr becomes [false, true]
  2. i = 1, length = 2, arr = [false, (true)]-> arr stays [false, true]

(parenthesis denotes current target)

Solutions:

  • Iterate down, not up

    for (let i = arr.length - 1; i >= 0; --i) if (!arr[i]) arr.splice(i, 1);
    
  • Use Array.prototype.filter instead (this will also improve readability)

    arr = arr.filter((item) => !!item);
    

The .filter() approach as suggested by Rossaini or PaulS is definitely a better path to follow. However, your approach works if you work through the array backwards:

const test=[7, "ate", "", false, 9];

function bouncer(arr) {
  if (!arr.length) return [];
  for (let i=arr.length-1; i--;){
    if(!arr[i]){
        arr.splice(i, 1)
      }
  }
  return arr;
}

console.log(bouncer(test));
console.log(bouncer([]));
// solution with filter:
console.log(test.filter(e=>e));

You need to consider that .splice() actually changes the source array you are working on. Using an increasing index i you will skip an entry each time an element is deleted from the array. By walking through the array backwards (from the end to the beginning) as done with for (let i=arr.length; i--;) you will avoid this problem.

There's a function for that

const noFalse = arr.filter(el => !!el)

You can try Array.prototype.filter

bouncer = arr =>  arr.filter(elm =>  !!elm)
var array = [ false, null, 0, "", undefined,NaN , true]
var newArr = bouncer(array )
console.log(newArr )

The Problem is, when you do splice, you are adjusting your indexes. You could have added a simple debug statement like console.log to identify whats happening with your code.

I just added a sample stdout line before doing validation


function bouncer(arr) {
  for(let i=0; i<arr.length; i++){
    console.log(arr[i]);
    if(!arr[i]){
        arr.splice(i, 1)
      }
  }
  return arr;
}
console.log(bouncer([7, "ate", "", false, 9]));

And your code does print as below

[/private/tmp]$ node sto.js
7
ate

9
[ 7, 'ate', false, 9 ]

So if you observe, after "" string, as you have used splice the index got adjusted and false missed from iteration.

Solutions

  1. Use another array and push all non invalid items into it.
  2. Use filter which does same for you automatically.
Related