4

Given an array with different data types. I write a function to find those values which are false and return the array without the falsy values.

For example:

[7, "ate", "", false, 9] should return [7, "ate", 9].

This is my current code:

function bouncer(arr)
{
    for (var i = 0; i < arr.length; i++)
    {
        if (Boolean(arr[i]) == false)
        {
            arr.splice(i, 1);
        }
     }
     console.log(arr);
}

However, there is a problem:

I.)

In case of Input: bouncer([7, "ate", "", false, 9])
It returns: [ 7, 'ate', false, 9 ]
But it should return: [7, "ate", 9]

II.)

In case of input: `bouncer([false, null, 0, NaN, undefined, ""]);`
It returns: [ null, NaN, '' ]
But it should return: []

I don't understand why it returns the boolean false values like NaN or null. But it correctly splices off values like empty strings ("") or undefined.

And I also don't understand, why in the first case it returns false (which is not intended), but in the second case it does not returns false.

Thank you very much for clarification.

Shidersz
  • 16,846
  • 2
  • 23
  • 48
S.H
  • 671
  • 2
  • 6
  • 22
  • 1
    JavaScript has the concept of "falsy", so use `===` instead of `==`. Read more here: https://developer.mozilla.org/en-US/docs/Glossary/Falsy – Dai Jan 08 '19 at 17:02
  • 2
    Don't change the array you're iterating over, unless you know what you're doing ;) Check the elements on each step. (Hint: What's happening with the elements after the element that gets removed?) – Andreas Jan 08 '19 at 17:03

5 Answers5

3

As other people says, you can use filter() for this purpose. The shortest way would be:

const array = [false, null, true, 0, NaN, undefined, "", "Hola Mundo"];
console.log(array.filter(Boolean));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

However, getting back to your code, you should note that splice() method will change the array when it detect a falsy value (because removes one element). In other words, the arr.length is decreasing dinamically while the loop executes, but the i variable keeps incrementing. This generates that the loop actually won't loop all the elements on the array. To fix this, you have to decrement the value of the variable i when you are removing an element from the array. Check next code:

function bouncer(arr)
{
    for (var i = 0; i < arr.length; i++)
    {
        if (Boolean(arr[i]) === false)
        {
            arr.splice(i, 1);
            i = i - 1;
        }
    }

    console.log(arr);
}

bouncer([false, null, true, 0, NaN, undefined, "", "Hola Mundo"]);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Shidersz
  • 16,846
  • 2
  • 23
  • 48
1

You almost done, but it would be better to check what values are falsy instead to compare them, so this function will do the trick

const getNonFalsyValues = (arr) => {
  return arr.reduce((arr, current) => {
    if (Boolean(current)) {
        arr.push(current);
    }
    return arr;
  }, []);
}

I hope it can help you.

Juorder Gonzalez
  • 1,642
  • 1
  • 8
  • 10
0

Simply use filter like this.

What filter does here is it add value in the output array only if it is true.

let arr = [false, null, 0, NaN, undefined, "", 1 , 123];
let op = arr.filter(value => value);
console.log(op)
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
0
const bouncer = (arr) => arr.filter(val => !!val);
korteee
  • 2,640
  • 2
  • 18
  • 24
0

In JavaScript some values evaluate to false, like null, empty string '' and undefined. You can check more about evaluation in JavaScript here.

Also you should use === instead of == in comparisons. See this.

Bruno Anken
  • 25
  • 2
  • 7