[why doesn't this approach work?] Falsy Bouncer

Hi all,

While I finally managed to solve the Falsy Bouncer challenge (using a different approach), I’m not sure why my original approach didn’t work.

I’d be most grateful for any insights into why this approach doesn’t work. Is there a way to make this work? Thanks in advance.

This is the code from my original approach:

function bouncer(arr) {

 let copyOfArray = arr;
 let result = [];

 for (let i = 0; i < copyOfArray.length; i++) {

   if (copyOfArray[i] === false || copyOfArray[i] === null || copyOfArray[i] === 0 || copyOfArray[i] === "" || copyOfArray[i] === undefined || copyOfArray[i] === NaN) {
     
     // This should remove 1 element at index "i".
     copyOfArray.splice(i, 1);
   }

 }
 console.log(copyOfArray);
 console.log(arr);
 return copyOfArray;

}

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

I thought ideally if this approach could be made to work, then I could keep it simple without having to use a different built-in method – which I did eventually have to use – to solve the challenge. (I won’t talk about the different method here to avoid spoiling it for others)

Thanks again for any help.

@camperextraordinaire , thanks so much for the response, really appreciate it.

Regarding the first thing you pointed out copyOfArray[i] === NaN → I had no idea it will never evaluate to true, that’s very helpful, thanks.

Regarding the second point copyOfArray.splice(i, 1) → this is very interesting, it never occurred to me that I am skipping over some elements.

I’m still a bit confused about this and this is what I think is happening.

  1. We call bouncer([7, "ate", "", false, 9])
  2. We loop through the values in the array. By the time when i = 2, since

copyOfArray[i] === ""

We then execute:

copyOfArray.splice(i, 1);

This removes what’s in index 2 of the array, namely “”.

The array now looks like this:

[7, "ate", false, 9]

We now iterate through the loop again and this time i = 3. Since we had deleted what was in index 2, now what’s in index 3 is actually the number 9. So in effect, the “for” loop never looked at the value false (which is now in index 2), as we basically skipped it.

I’d be most grateful if you could let me know whether that’s an accurate assessment, thanks in advance.

As for the following:

let copyOfArray = arr

I had no idea that doesn’t create a copy of arr. I just looked up how to clone an array and it looks like JavaScript gives you so many different ways of doing so… it’s pretty confusing… :scream: :flushed: – I need to look into this a bit more.

Thanks again for your help, really appreciate it.

@camperextraordinaire , thank you!!

Array cloning is something which I found more interesting than is probably healthy :rofl:
You will most likely come across this again when you complete later challenges in this course.

Here is an instructive FCC article about shallow copies v true cloning of arrays in Javascript.

In essence, there are many methods which can create shallow copies of arrays, which means that if an array is multi-dimensional, the deeper levels will be references to the original only and thus could mutate the original. The only method I know of which creates a complete clone and avoids mutation altogether is:

let array2 = JSON.parse(JSON.stringify(array1));
1 Like

@igorgetmeabrain and @camperextraordinaire , thanks for the feedback, really appreciate it.

I think it will take me some time to get my head around all the different approaches.

I’ll have to check out the links to try to understand all the nuances, thanks again.

Keeping in mind the cloning and splice stuff, this is why you should generally tackle these problems from the opposite direction for filtering. Instead of creating a copy and removing items you don’t want, you should create a new array and only insert what you need.

For reference I’ll show how to keep only even numbers from an array of numbers nums using three functionally equivalent methods. In my opinion, each method is successively easier to understand than the previous.

function copyAndRemovalFilter(nums) {
  const result = Array.from(nums);
  for (let i = 0; i < result.length; i++) {
    if (result[i] % 2 !== 0) {
      result.splice(i, 1);
      i--;
    }
  }
  return result;
}
function buildUpFilter(nums) {
  const result = [];
  for (const num of nums) {
    if (num % 2 === 0) {
      result.push(num);
    }
  }
  return result;
}
function justUseTheBuiltinFilter(nums) {
  return nums.filter((num) => num % 2 === 0);
}
1 Like

@colinthornton , wow this is really insightful, really interesting stuff, thanks!

The solution I did use to solve the challenge is with the .filter built-in method. I had to do a google search to learn about this method.

I think the second solution you shared (ie using the .push method) is really interesting. In a way I prefer it because if I had thought of this approach, I may have been able to solve the challenge using what I already knew, without having to search online for a built-in method.

Thanks again. In the future, I’ll know I can approach these types of problems in these two ways. (I don’t think I’ll use the .splice method given that it can lead to problems as @camperextraordinaire pointed out, although you did show that it can be made to work).

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.