131

In certain situations, it may happen that we have undefined or generally falsy values in Array structures. For instance when reading and filling data from some unknown sources like Databases or HTML structures. Like

var data = [42, 21, undefined, 50, 40, undefined, 9]

Since that might cause trouble when looping over such arrays and working on the elements, what is the best practice to remove undefined (falsy values) ?

jAndy
  • 231,737
  • 57
  • 305
  • 359

15 Answers15

218

To use Array.prototype.filter here might be obvious. So to remove only undefined values we could call

var data = [42, 21, undefined, 50, 40, undefined, 9];

data = data.filter(function( element ) {
   return element !== undefined;
});

If we want to filter out all the falsy values (such as 0 or null) we can use return !!element; instead.

But we can do it slighty more elegant, by just passing the Boolean constructor function, respectively the Number constructor function to .filter:

data = data.filter( Number );

That would do the job in this instance, to generally remove any falsy value, we would call

data = data.filter( Boolean );

Since the Boolean() constructor returns true on truthy values and false on any falsy value, this is a very neat option.

Ivan Castellanos
  • 8,041
  • 1
  • 47
  • 42
jAndy
  • 231,737
  • 57
  • 305
  • 359
131

Inline using lambda

result.filter(item => item);
raphaklaus
  • 1,645
  • 1
  • 10
  • 8
  • 14
    this one will remove all falsey values. Since the OP specified falsey values being unwanted, this is definitely the best answer IMO. However, thy also specifically point out undefined at which point you'd want `result.filter(item => item !== undefined)` – Braden Rockwell Napier Oct 30 '17 at 23:12
  • 4
    `[true,false,undefined,null,'a',1,0,'0'].filter(x=>x)` returns `[true, "a", 1, "0"]` – frumbert Sep 26 '18 at 01:51
  • 1
    best answer here – Omar Jul 15 '19 at 19:15
  • JS newby here. People say this is the best answer but why is this better than `filter(Boolean)` or `filter(item => !!item)` – Adam Hughes Jun 14 '22 at 20:42
  • 1
    @AdamHughes It's not, ppl often overvalue brevity compared to clarity. Of the 3, `filter(item => !!item)` would actually be the best bc it clearly communicates that you're filtering on the truthiness of item. `Boolean` would be the worst bc both the input and operation are no longer explicit. Plus it looks like you're filtering for booleans, which is definitely not what it does. – John Neuhaus Jun 27 '23 at 19:34
30

You can use lodash compact method, which removes null, undefined and ''.

_.compact(data)
leonheess
  • 16,068
  • 14
  • 77
  • 112
Akash Dathan
  • 4,348
  • 2
  • 24
  • 45
26
[NaN, undefined, null, 0, 1, 2, 2000, Infinity].filter(Boolean)
//[ 1, 2, 2000, Infinity ]
Anil
  • 523
  • 1
  • 8
  • 16
22

If you have an array of objects and want to remove all null and undefined items:

[].filter(item => !!item);
Diogo Capela
  • 5,669
  • 5
  • 24
  • 35
20

ES6 single line

data.filter(e => e)
Rejo Chandran
  • 599
  • 4
  • 22
16
data.filter(Boolean)

Is the most short and readable way to do it.

Yan Takushevich
  • 1,843
  • 2
  • 18
  • 23
  • 3
    Why does this work? Don't just post "magic" explain also how it works and why this is a good solution. – Lucian Enache Feb 26 '21 at 10:40
  • 1
    @LucianEnache it applies Boolean function for every item of the array and if it converts to false, it filters it out. Read more here: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Boolean – Yan Takushevich Mar 25 '22 at 08:22
  • Why is the resulting array, still typed as potentially containing undefined? – SeanMC Dec 07 '22 at 16:52
  • 2
    @SeanMC It's another question, concerning typescript. It doesn't play well with array.filter. You can find additional info on this topic here: https://stackoverflow.com/questions/43010737/way-to-tell-typescript-compiler-array-prototype-filter-removes-certain-types-fro – Yan Takushevich Dec 08 '22 at 10:32
  • The most short way to say most short is shortest. It's also the readablest way. – jox Mar 05 '23 at 01:27
5

As Diogo Capela said, but where 0 is not filtered out as well.

[].filter(item => item !== undefined && item !== null)
Akber Iqbal
  • 14,487
  • 12
  • 48
  • 70
3
var a =  ["3","", "6"];
var b =  [23,54,56];
var result = [];

for (var i=0;i<a.length;++i) {
    if (a[i] != "") {
        result[i] = b[i];
    }
}

result = result.filter(function( element ) {
   return element !== undefined;
});

console.log(result);
Jorge Londoño
  • 588
  • 2
  • 14
3
var arr1 = [NaN, 0, 15, false, -22, '',undefined, 47, null];

var array1 = arr1.filter(function(e){ return e;});

document.write(array1);

single lined answer

ROOT
  • 11,363
  • 5
  • 30
  • 45
vishal
  • 381
  • 2
  • 4
1

Array.prototype.reduce() can be used to delete elements by condition from an array but with additional transformation of the elements if required in one iteration.


Remove undefined values from array, with sub-arrays support.

function transform(arr) {
    return arr.reduce((memo, item) => {
        if (typeof item !== "undefined") {
            if (Array.isArray(item)) item = transform(item);
            // We can transform item here.
            memo.push(item);
        }
        return memo;
    }, []);
}

let test1 = [1, 2, "b", 0, {}, "", , " ", NaN, 3, undefined, null, 5, false, true, [1, true, 2, , undefined, 3, false, ''], 10];

console.log(transform(test1));

Try it on jsfiddle.net/bjoy4bcc/

1

in ES6 this can be achieved by simply using using filter with function return the value like this:

const array = [NaN, 0, 15, false, -22, '',undefined, 47, null];
const filteredArr = array.filter(elm => elm);
console.log(filteredArr);
ROOT
  • 11,363
  • 5
  • 30
  • 45
1

The solution with Array.filter will actually keep the array unchanged and create a new array without the undesired items. If you want to clean an array without duplicating it, you can use this:

for (var i = data.length-1; i >= 0; i--) {
    if (!data[i]) {
        data.splice(i, 1);
    }
}
maxime schoeni
  • 2,666
  • 2
  • 18
  • 19
0

If you are in Typescript and want to return an Array of strings vs from Array<string|undefined> try one of these...

var arr = ['a', 'b', 'c', undefined, 'e', undefined, 'g'];
var solutionA = arr.reduce((acc, item) => {
    item && acc.push(item);
    return acc;
}, []);

console.log('solution a', solutionA);

var solutionB = [];
arr.forEach((each) => each && solutionB.push(each), []);

console.log('solution b', solutionB);

arr.forEach((each,index) => (!each) && arr.splice(index,1),[]);
console.log('solution c', arr);
publicmat
  • 781
  • 5
  • 6
-4
var data = Object.keys(data)

This will remove undefined values but array index will change

SANTHOSH.SJ
  • 343
  • 1
  • 4
  • 7