Function working partially

Tell us what’s happening:

I am looping through all the array elements and checking for any falsy values usinf if loop, but the function only removes the first falsy value i.e. “” and it does not remove false. Why is it happening? Why is it not removing the second array element?

P.S. : I have used splic function to remove the element from an array.

Your code so far


function bouncer(arr) {
// loop through arrayvalues one by one
for (let i = 0; i < arr.length; i++) {
  // console.log('length',arr.length)
  if (arr[i] === false || arr[i] === null || arr[i] === null || arr[i] === 0 || arr[i] === "" || arr[i] === undefined || arr[i] === NaN) {
    console.log('the array to be removed',arr[i])
    console.log('index of the array',i)
    arr.splice(i,1)
    console.log('array after removing the falsy value',arr)
  }
}
console.log('array outside the function',arr)
return arr;
}

bouncer([7, "ate", "", false, 9]);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36.

Challenge: Falsy Bouncer

Link to the challenge:

I suggest you take a different approach to this.

Instead of using splice to remove values from the arr argument (SIDE EFFECTS!), create a new array before the for loop, and push elements that are truthy onto it, then return the new array.

Secondly, I think the point of this exercise is to teach you that you can simply throw the value as it is into an if statement, and the if block will be run if the value’s truthy. Like so:

if (arr[i]) {
  // code to execute if arr[i] is truthy
}

if (!arr[i]) {
  // code to execute if arr[i] is falsy
}

Hey colinthornton the above solution works absoultely fine and it passed the tests. But i am curious why the solution i tried previously didn’t worked out. When i printed what values are omitted from the array i was seeing that only the first falsy values were not getting pushed. So, i am not getting this point that why only first falsy values was getting omitted and not others.

It would be much appreciated if you could help me out on that one.

That’s because you were mutating the array which you were iterating. When encountered falsy value splice() were removing that element from the iterated array, this means that after iteration with i = 2 and removing "" from array, false took that place. Arr at that point was [ 7, 'ate', false, 9 ], next iteration was with i = 3 (and arr[3] in the mutated array was 9). Due to array mutation one element was completely missed.

2 Likes

@sanity answered your question so I’ll talk about something else.

You should never mutate object arguments in a function (arrays are objects). splice mutates arrays (it changes them in place), so, as I said above you should not call it directly on function arguments. Let’s try something with a function called getTail, which takes an array and returns an array with all but the first element of the input.

// creates side effects - don't try this at home
function getTail(arr) {
  arr.splice(0, 1);
  return arr;
}

const someNums = [1, 2, 3, 4, 5];
const someLessNums = getTail(someNums);

console.log(someNums);
console.log(someLessNums);

You might want to believe that the logs would look like this:

[1, 2, 3, 4, 5]
[2, 3, 4, 5]

But you’d be wrong! Why? Because the getTail function creates a side effect by mutating someNums directly with splice. The actual log output is this:

[2, 3, 4, 5]
[2, 3, 4, 5]

So what should we do instead? As I suggested, create a new array that we work on and return that. There are several ways to rewrite getTail without creating side effects so I’ll showcase a handful that come to mind.

With array destructuring:

function getTail(arr) {
  const [head, ...tail] = arr;
  return tail;
}

With slice:

function getTail(arr) {
  return arr.slice(1);
}

With a for loop:

function getTail(arr) {
  const tail = [];
  for (let i = 1; i < arr.length; i++) {
    tail.push(arr[i]);
  }
  return tail;
}

Thanks for the explanation. It is now clear why y solution was not working. Much Appreciated.