Tom Sun
Tom Sun

Reputation: 61

Array.prototype.filter automatically filtering out falsey value

Does the filter function automatically filter out falsey values such as false, null, or undefined? If so, how to stop it from doing that.

I need to filter out all 0 in an array, so I used array.filter callback, and I realized that the filter function removes falsey values, even when I want to keep them. Is there a way around this?

EDIT: This is the code that I have, and doing a deep comparison didn't return the falsey values.

function removeZero(arr) {
  return arr.filter(function(element){
    if(element!==0){
      return element;
    }
  });
}

EDIT 2: Here's the repl.it link that contains a test array content, and when I ran it the result filters out false, null, and undefined. https://repl.it/BAiK

Upvotes: 3

Views: 1581

Answers (3)

C.Morris0987
C.Morris0987

Reputation: 34

just

[1,2,3,0,[],{},false,undefined].filter(Boolean)  // return [1, 2, 3, [], {}]

here Boolean is a function, which when all the falsy value come in, it will return false

Upvotes: 1

jperelli
jperelli

Reputation: 7207

Use the !== operator

[1,2,3,0,[],{},false,undefined].filter(function(e){return e !== 0})
// Output: [1, 2, 3, Array[0], Object, false, undefined]

compare with the output of the != operator (which you don't want to use)

[1,2,3,0,[],{},false,undefined].filter(function(e){return e != 0})
// Output: [1, 2, 3, Object, undefined]

This is the code you provided https://repl.it/BAiK

var removeZeros = function (arr) {
  return arr.filter(function(element){
    if(element!==0){
      return element; // here is the error, you need to return a boolean. (true to add element to final array, false to ignore element)
    }
  });
}

console.log(removeZeros([false, 1, 2, 3, null, 0, 4, undefined, 5, 0]));
// Output: [ 1, 2, 3, 4, 5 ]

You see, the return value for the filter function needs to be a boolean value, not the element you want to return. When you return false, the element is not added to the final array, when you return true, the element being processed is returned. See my edit with your code fixed

This is your code fixed

var removeZeros = function (arr) {
  return arr.filter(function(element){
    return element !== 0 // this returns a boolean
  });
}

console.log(removeZeros([false, 1, 2, 3, null, 0, 4, undefined, 5, 0]));
// Output: [ false, 1, 2, 3, null, 4, undefined, 5 ]

Upvotes: 5

Nina Scholz
Nina Scholz

Reputation: 386746

var result = [1, 2, 3, 0, false, undefined, null, -1].filter(
    function (e) { 
        return e !== 0;
    });
document.getElementById('out').innerHTML = result.reduce(function (r, a) { return r + '\n    ' + a + ' [' + (typeof a) + ']'; }, '[') + '\n]';
<pre id="out"></pre>

your example does not return true, but the value itselft, which is evaluated. Array.filter() include the element if the return value is truthy.

function removeZero(arr) {
    return arr.filter(function(element) {
        if (element !== 0){
            return element; // <-- falsy values are not true.
        }
    });
}

Upvotes: 1

Related Questions