Why returning undefined in array as output?

Tell us what’s happening:

I tired using map ,passed current element and index, checked whether current element is falsy?
then i tired to remove from the array using splice method.

Your code so far


function bouncer(arr) {
// Don't show a false ID to this bouncer.

let newarr=arr.map((el,i)=>{
    if(Boolean(el)===false){
        arr.splice(i,1);
    }  
});
return newarr;
}

console.log(bouncer([7, "ate", "", false, 9]));
// [ undefined, undefined, undefined, undefined,  ] 

Your browser information:

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

Challenge: Falsy Bouncer

Link to the challenge:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/falsy-bouncer

First you should not be mutating the array you are mapping over. You seem to not understand how the map method works. The function supplied to it expects you to explicitly return a value during each iteration to be assigned to the same index in a new array. Since you do not return a value, the value undefined gets returned instead, so the final array just has a bunch of undefined values.

In addition to the MDN documentation above, I suggest you work through the FCC challenges below to help you better understand what the map method does.

2 Likes

Mr RandellDawson
1.Why should i not mutate the orignal array on which i am mapping? is it a bad practice?

function bouncer(arr) {
  // Don't show a false ID to this bouncer.

  let newarr=arr.map((el,i)=>{
      if(!Boolean(el)){
           arr.splice(i,1);
      }
      return el;
      
  });
  return newarr;
}

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

console.log(x);
console.log(x[4]);
// [ 7, 'ate', '', 9,  ]
// undefined
  1. Above function does not evaluate Boolean("")as false why ?? You can confirm this in returned array.
  2. Why the last element of array is undefined ? Since i returned the value.

I tried using live Programming Mode , i was unable to understand why it returned undefined as last element.
If you can help please.
Thanks

  1. Correct do no mutate the array!
  2. It does evaluate as false, you have other issues
  3. See below

Look at the Visualize Code again ( paste code here: http://pythontutor.com/javascript.html#mode=edit )

What happens to arr around step 10-11?

in your .map Method when i=4, what is arr equal to ? and what is arr[4]?

Once you answers these it should answer your #1 question and we can hint you into a different approach to filter the array for this challenge :slight_smile:

1 Like

Around step 10-11 Boolean("") evalutes to true and it returns as el. Same this does not happen with Boolean(false). ?? Why is this happening i don’t understand
I got that map is running till i=4 , i think it is because i remove the a element from original array now at i=4 nothing exist

Boolean("") is false … but !Boolean("") is true … so line 6 (in the image below) is run which mutates the array.

'' is removed and now arr[2] is false and arr[3] is 9

STEP 10:

STEP 11:

1 Like

Ok so i changed the line if(Boolean(el)===false) rest is same. But the output is same :blush: Why?

Boolean(el)===false) is the same as ! Boolean(el) :slight_smile:

Is there maybe another array Method you could use that would filter the results for a True/False value and you wouldn’t need to you Boolean() at all?

1 Like

Yes i did it using

let newarr=[];
for(let i=0;i<arr.length;i++){
    if(Boolean(arr[i])){
      newarr.push(arr[i]);
    }  
}
  return newarr;

It passes all the test result. Using filter i guess it will go like this arr.filter( falsy=>Boolean(falsy))

1 Like

I wanted to use map somehow, now after running this piece of code below i am sure that if u don’t return any thing in map by default it will return undefined. I think we cannot skip returning undefined in map.

function bouncer(arr) {
let newarr=arr.map((el,i)=>{
      if(Boolean(el)!==false){
          return el
      }
           
  });
  return newarr;
}

console.log(bouncer([7, "ate", "", false, 9]));
//[ 7, 'ate', undefined, undefined, 9 ]

:grin::blush::innocent:

1 Like

Congrats! I like the arr.filter( falsy=>Boolean(falsy)) answer!

Ya, map was not the best approach here… i mean you could have used it but it’s not really what it is for:

function bouncer(arr) {
  // Don't show a false ID to this bouncer.
  let temp = []
  arr.map( i => {if(Boolean(i)) temp.push(i)})
  return temp
}
bouncer([7, "ate", "", false, 9]);

You can kind of hack it together (basically your code using map or forEach) but best to use filter when looking for a true/false thing; such as “Is user online?” … use filter.

1 Like

Thank you so much. i appreciate it

1 Like

Instead of using map as shown above, to each is better because map does generate a new array that is not used. It just consumes extra memory unnecessarily.

1 Like

So Mr Randell from where i can read about it. I know you know it by experience. What other things should i read