More basic Falsey Bouncer solution - why doesn't it work?

Hello folks. So I understand the Advanced solution with .filter, but I’m not understanding why my original attempt doesn’t quite work:

function bouncer(arr) {
  // Don't show a false ID to this bouncer.
  arr.forEach((item) => {
    if (!item) {
      arr.splice(arr.indexOf(item), 1);
    };
  });
  return arr;
}

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

The empty string array member is removed, but the actual ‘false’ boolean member is not. I’d like to understand what exactly is happening. Thanks!
Steve

I added a console.log inside your function to log the value and its index on each iteration, and here’s the output:

item: 7, index: 0
item: ate, index: 1
item: , index: 2
item: 9, index: 3

Looks like forEach skips that value. When it gets to the empty string (index 2), your function removes that element from the array and index 2 then belongs to the false value. However, forEach then goes on to the next index (3).

1 Like

As @ArtemPetrov noticed, the element with false disappears; it’s because you’re changing the length of the array, and forEach just moves into the next index after you do that. This may seem like a more basic solution, but it’s actually a lot more complex because you’re mutating the thing you’re working on, which makes it incredibly difficult to reason about — unless you have a very good reason for doing it (ie you have very specific memory constraints, which is extremely unlikely), I would try very hard not to do this

2 Likes

Many thanks, that makes perfect sense! I was thinking it had to do with deleting array members, but wasn’t sure how forEach actually keeps track as it iterates. Great explanation!

Steve

@Dan - no wonder I was giving myself headaches! Thanks for the reply and tip. I will try to recognize and avoid this trap.

Steve

1 Like