1589

How do I remove empty elements from an array in JavaScript?

Is there a straightforward way, or do I need to loop through it and remove them manually?

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
Tamas Czinege
  • 118,853
  • 40
  • 150
  • 176
  • 26
    It would be helpful if your question had specified exactly what you mean by "empty elements", since most of the answers here interpret that incorrectly (IMHO) to mean "falsey" elements. NB: there is a difference between what you get for `var a = [,,]` and `var a = [undefined, undefined]`. The former is truly empty, but the latter actually has two keys, but with `undefined` values. – Alnitak Dec 29 '15 at 11:30
  • Not quite an answer, but I would say it's better practice to try to avoid `null`/`undefined` in an array in this first place as much as you can. For instance, if your `null`s come from mapping over another array with the map function returning `null` for certain elements, try to `Array.filter` out those elements prior to running the map. Makes your code more readable/self-documenting. Obviously, this doesn't work for every use case, but it can be applied to a lot. – Luke Redmore Aug 11 '21 at 17:01

50 Answers50

1756

A few simple ways:

var arr = [1,2,,3,,-3,null,,0,,undefined,4,,4,,5,,6,,,,];

arr.filter(n => n)
// [1, 2, 3, -3, 4, 4, 5, 6]

arr.filter(Number) 
// [1, 2, 3, -3, 4, 4, 5, 6]

arr.filter(Boolean) 
// [1, 2, 3, -3, 4, 4, 5, 6]

or - (only for single array items of type "text")

['','1','2',3,,'4',,undefined,,,'5'].join('').split(''); 
// output:  ["1","2","3","4","5"]

or - Classic way: simple iteration

var arr = [1,2,null, undefined,3,,3,,,0,,,[],,{},,5,,6,,,,],
    len = arr.length, i;

for(i = 0; i < len; i++ )
    arr[i] && arr.push(arr[i]);  // copy non-empty values to the end of the array

arr.splice(0 , len);  // cut the array and leave only the non-empty values
// [1,2,3,3,[],Object{},5,6]

jQuery:

var arr = [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,];
    
arr = $.grep(arr, n => n == 0 || n);
// [1, 2, 3, 3, 0, 4, 4, 5, 6]
vsync
  • 118,978
  • 58
  • 307
  • 400
  • The other answers didn't work for me becuase i had an array of arrays. This works great though +1. – Timothy Ruhle Feb 16 '11 at 01:06
  • 37
    earliest IE support for filter is IE9 standards mode. – yincrash Nov 02 '11 at 02:19
  • 21
    for pure javascript it should be `arr = arr.filter(function(n){return n; });` – ilumin Jan 12 '13 at 08:38
  • @yincrash - as I wrote in my first comment – vsync Jan 12 '13 at 20:04
  • Given answer doesn't work. You need to return the element, as noted by @ilumin. E.g. `[1,null,undefined,3,].filter(function(){;return true})` => `[1, null, undefined, 3]` – broofa Feb 16 '13 at 18:32
  • @broofa - it does work. just tried it on IE, FF and CHROME. from W3C: `filter calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a true value.`. and 'undefined' is not an empty value by the way, so as null. – vsync Feb 17 '13 at 00:11
  • @vsync - This is a matter of semantics, where it depends on what is meant by "empty". It obviously should include cases where `(key in array) == false`, which is what your solution filters on. But I'm pretty confident that most people would also expect this to include the case where `(key in array) && (array[key] === undefined)` as well, which your solution doesn't handle. – broofa Feb 18 '13 at 14:20
  • @broofa - well, you are right and you are wrong, because I answered the OP's question in the exact manner he needed, but it is true that if you want to detect 'undefined' (which is NOT considered an empty value) than you need to change the filter function – vsync Feb 18 '13 at 15:04
  • 28
    `foo.join("").split("")` only seems to work if the strings are single characters – Atav32 Jul 26 '13 at 16:32
  • 15
    Your pure JavaScript code has a bug. If the array has a value with "0" in it, the value will be filtered out because "0" is falsy. What you want is: arr.filter(function (n) { return (n !== undefined && n !== null); }); – John Kurlak Mar 07 '14 at 21:55
  • @JohnKurlak - you're right, I fixed it, but not like you've said. – vsync Mar 08 '14 at 09:29
  • jQuery should have a built in method for that. Or even ES6! – Augustin Riedinger May 03 '14 at 10:56
  • 13
    ES6 can do it even simpler `arr.filter(e=>e)` and this can be chained by map, reduce, etc. – Sheepy Feb 09 '15 at 04:32
  • @Sheepy - cool, but it would take forever for ES6 to become a standard – vsync Feb 09 '15 at 10:40
  • @vsync Forever may come faster than you think, because the browsers have agreed to push questionable stuffs to ES7. IE technical preview have most ES6, and production Firefox can already fun this code. – Sheepy Feb 09 '15 at 10:44
  • yeah, that's what they said about ES5, I remember that day. and still, hardly anyone is using ES5...by the time ES7 will come, humans will be living on mars – vsync Feb 09 '15 at 10:50
  • @vsync, as @JohnKurlak mentioned, ```arr = arr.filter(Number)``` is still wrong and you should remove it from the answer – sahbeewah Apr 07 '15 at 03:39
  • 2
    As several people pointed out, `arr.filter(n => n)` and its es5 equivalent will remove falsy values, which may not be desired. However filter, like other array methods, only iterates over defined values anyway. Thus `filter(n => true)` is a nice clean way to condense a sparse array. – Semicolon Aug 25 '15 at 02:07
  • @ayushi it shouldn't - it confuses the original question by mostly removing _falsey_ entries rather than _missing_ entries. – Alnitak Nov 23 '15 at 11:59
  • 1
    @Alnitak - I confused nothing, I simply extended the original question because it is more likely that people who come here from Google will be interested in both removing empty items as well as providing them the solutions of removing other kind of items which might be considered "empty" to them, in some situations. – vsync Nov 23 '15 at 15:53
  • `$.grep(arr,function(n){ return n == 0 || n });` will keep value `0` in the array :) – Tân Dec 11 '15 at 07:50
  • @DavChana - Your comment is irrelevant to this discussion. you can use the above answer's code however you wish, you are free to modify it if you prefer `!==` instead of `!=`... – vsync Oct 26 '16 at 15:50
  • Better ```typeof n !== 'undefined'``` instead of ```n != undefined``` – cnexans Aug 29 '17 at 13:02
  • @cnexans - Do you have a scenario which can back the claim? – vsync Sep 01 '17 at 13:48
  • ```n != undefined``` may have two problems: 1. With variables that are not yet defined, it will throw an error 2. Undefined can be redeclared (not in the global scope) i.e. ```function example() { var undefined = 1; }```. Using ```typeof n != 'undefined'``` is a way to always prevent these (horrible but possible) cases. – cnexans Sep 03 '17 at 00:05
  • @cnexans - Thank you but respectfully disagree. Those are ridicules edge-cases that I've never ever encountered in all my years of coding in javascript. Have you? If you get so deep into thinking about any absurd edge case there will be no end. this is why developers obey the rules and do not create variables named `undefined`. else, the code will punish them with bugs, which they well deserve for. – vsync Sep 03 '17 at 11:36
  • this => // ES6 style (Firefox FTW) arr.filter(n => true) // [1, 2, 3, 3, null, 0, undefined, 4, 4, 5, 6] !! – Ramakay Dec 24 '17 at 18:33
  • Regarding $.grep, is there a way to log/capture all removed values and their IDs in the faulty/unmodified array? I think this information can be useful to sync with other arrays that may be related to the one cleaned from empty and false values. – Jonathan Arbely Jan 15 '18 at 11:55
  • `delete temp;` - This has no effect in JavaScript, as it can only be performed against object properties - attempting to access `temp` after this line will result in the same output as if you hadn't done `delete temp;` in the first place. – Jamie Ridding Jul 11 '19 at 22:56
  • How to make it work in array of object? – Irvan Hilmi Sep 14 '22 at 08:22
  • let a = [new Object, new Object, new Object]; delete a[0]; a.filter(function(n) { console.log(n); return App.isset(n); }); console.log(a); – Irvan Hilmi Sep 14 '22 at 08:25
  • a still has an empty value from deleted a[0] – Irvan Hilmi Sep 14 '22 at 08:26
  • @vsync how can we achieve this in an array of arrays const data = [ [12.123, 13.124, 14.125, 15.126, 126.127, 127.128, null, null, null, null], [0.56, 0.52, 0.5, 0.49, 0.46, null, null, null, null], [null, null, null, null], ]; – JSG Sep 22 '22 at 07:36
  • @GauravSuhanda - if they are the same length, iterate one and check if current value is inside the other, and add the result to a third new array, or just join both arrays and run my solution – vsync Sep 22 '22 at 07:48
1468

EDIT: This question was answered almost nine years ago when there were not many useful built-in methods in the Array.prototype.

Now, certainly, I would recommend you to use the filter method.

Take in mind that this method will return you a new array with the elements that pass the criteria of the callback function you provide to it.

For example, if you want to remove null or undefined values:

var array = [0, 1, null, 2, "", 3, undefined, 3,,,,,, 4,, 4,, 5,, 6,,,,];

var filtered = array.filter(function (el) {
  return el != null;
});

console.log(filtered);

It will depend on what you consider to be "empty" for example, if you were dealing with strings, the above function wouldn't remove elements that are an empty string.

One typical pattern that I see often used is to remove elements that are falsy, which include an empty string "", 0, NaN, null, undefined, and false.

You can pass to the filter method, the Boolean constructor function, or return the same element in the filter criteria function, for example:

var filtered = array.filter(Boolean);

Or

var filtered = array.filter(function(el) { return el; });

In both ways, this works because the filter method in the first case, calls the Boolean constructor as a function, converting the value, and in the second case, the filter method internally turns the return value of the callback implicitly to Boolean.

If you are working with sparse arrays, and you are trying to get rid of the "holes", you can use the filter method passing a callback that returns true, for example:

var sparseArray = [0, , , 1, , , , , 2, , , , 3],
    cleanArray = sparseArray.filter(function () { return true });

console.log(cleanArray); // [ 0, 1, 2, 3 ]

Old answer: Don't do this!

I use this method, extending the native Array prototype:

Array.prototype.clean = function(deleteValue) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == deleteValue) {         
      this.splice(i, 1);
      i--;
    }
  }
  return this;
};

test = new Array("", "One", "Two", "", "Three", "", "Four").clean("");
test2 = [1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,];
test2.clean(undefined);

Or you can simply push the existing elements into other array:

// Will remove all falsy values: undefined, null, 0, false, NaN and "" (empty string)
function cleanArray(actual) {
  var newArray = new Array();
  for (var i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

cleanArray([1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,]);
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 121
    WARNING: The 2nd option will remove any elements from an array considered "falsy," i.e. the values of false, 0, null & undefined. This array would end up with nothing at all in it: [null,,,0,,0,0,0,false,null,0] even though I might want the elements with values of 0, as in this array: [1,0,1,0,0,1] – Jason Bunting Nov 11 '08 at 16:48
  • Yes the second method, but the first one you pass the value of the elements that you want to delete [null,,,0,,0,0,0,false,null,0].clean(null) == [0,0,0,0,false,0] – Christian C. Salvadó Nov 11 '08 at 16:49
  • 5
    I realize that - which is why I only spoke of the second option. As for the first one, it is so narrow in scope that I would hesitate to make it part of the Array's prototype. See Alnitak's answer on this page for something that would be more ideal. Yours does allow for chaining though, obviously. – Jason Bunting Nov 11 '08 at 17:02
  • 1
    Your first solution is really nice if you don't have access to the "filter" method. Else I believe Alnitak's answer is better. – Joe Pineda Nov 11 '08 at 18:06
  • And what has the best performance? 1) or 2) approach? (or something like jQuery.grep() / Array.filter ) – AlfaTeK Feb 22 '10 at 11:24
  • 2
    @AlfaTek - on all apart from the newest browsers #2 will have the best performance, because arrays in JS aren't really arrays. The `splice` call is _really_ expensive on older browsers because they have to renumber all of the array keys to close up the gap. – Alnitak May 10 '11 at 19:35
  • i love how so many of those best answers are native extensions while so many people preach how evil it is – Gad Apr 04 '13 at 10:32
  • Also, you could write your loop a bit more performant by avoiding counting array elements on every loop like so: for(var i = 0, j = actual.length; i – Jorre May 11 '13 at 12:33
  • @neonski your suggestion didn't work for me. I tried results['data'] = results['data'].slice(0); and results['data'] still contains null values – mila Nov 26 '14 at 09:14
  • I can't believe how many votes this and the 2nd answer are getting. Neither actually answer the question that was asked. – Alnitak Feb 24 '15 at 17:15
  • WARNING: the first method could make `for (i in array)` to fail. To prevent it you should place a `if (array.hasOwnProperty(i)) {` inside the loop. – David Jul 04 '15 at 08:24
  • 1
    @David no, in modern code you should _safely_ extend `Array.prototype` using `Object.defineProperty` to make the new function a _non-enumerable property_ and then avoid the performance hit caused by putting `.hasOwnProperty` in every loop. – Alnitak Nov 23 '15 at 11:57
  • downvote because its outdated. you can do this with a oneliner nowadays. `const filteredArray = unfilteredArray.filter(item => *condition to keep item in array*)` – Dude Aug 14 '18 at 11:13
  • Another short and beautiful way using ECMA 5 could be `[1, 2,,, 3,,,,,,,,, 4,, 4,,, 5,,, 6,,,,,].filter( e => e !== ('' || null || undefined))` – creep3007 Aug 15 '18 at 06:51
  • @Miquel, you're right, I have updated the answer, it has been almost 10 years! – Christian C. Salvadó Oct 10 '18 at 18:13
  • array `[,'d','x']` with `return el != null` return `,d,x` while if I used `return el` I get the correct result `d,x` why is that ?? – zac Jun 30 '19 at 17:06
  • "You can pass to the filter method, the Boolean constructor function,..." is that correct? Seems like Boolean is used as a function, If I understand 'Boolean constructor function' then it should be creating an object. But 'typeof Boolean' returns 'function', and 'Boolean.constructor === Boolean' returns false. That code has some misleading aspects - it uses filter's behaviour to skip - 'callback is invoked only for indexes of the array which have assigned values'. filter( Boolean ) and filter( Number ) and filter( eval ) get rid of falsy values and unassigned (empty) indexes. – JoePythonKing Sep 10 '20 at 09:01
  • 1
    `Old answer: Don't do this!` <- why not? what if you have to do it in-place because you want to update references to array as well? Then splice is the most useful part of this answer. I guess the better answer is to avoid putting nulls in the first place. – nurettin Feb 22 '23 at 17:08
  • Most answers focus on creating a new array by copying old without "empty" elements. This one gives the answer to actual question of removing empty elements from existing array (if only in the "do not do this" section). – smokku Jul 20 '23 at 10:01
265

If you need to remove ALL empty values ("", null, undefined and 0):

arr = arr.filter(function(e){return e}); 

To remove empty values and Line breaks:

arr = arr.filter(function(e){ return e.replace(/(\r\n|\n|\r)/gm,"")});

Example:

arr = ["hello",0,"",null,undefined,1,100," "]  
arr.filter(function(e){return e});

Return:

["hello", 1, 100, " "]

UPDATE (based on Alnitak's comment)

In some situations you may want to keep "0" in the array and remove anything else (null, undefined and ""), this is one way:

arr.filter(function(e){ return e === 0 || e });

Return:

["hello", 0, 1, 100, " "]
Soviut
  • 88,194
  • 49
  • 192
  • 260
lepe
  • 24,677
  • 9
  • 99
  • 108
142

Simply one liner:

[1, false, "", undefined, 2].filter(Boolean); // [1, 2]

or using underscorejs.org:

_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
  • 1
    This is really cool - I have a newb question though: it looks like you're using a class name as a function call -- is that typecasting? I haven't seen this before and am not sure I get why passing `Boolean` works as a function... – Andrew Feb 03 '13 at 00:50
  • 9
    If you treat `Boolean` as a function it will simply return `true` or `false` wether the value is truly/falsy. – Andreas Louv Feb 07 '13 at 16:38
  • 9
    You're not *treating* Boolean as a function; it *is* a function. (A completely normal function, except that it's natively-implemented.) Somebody needs to do a little research on the JavaScript object model. ;) – ELLIOTTCABLE Feb 24 '15 at 17:28
  • @ELLIOTTCABLE Im just gonna leave this here, `(true).constructor === Boolean`. And then tell me if we can do this with other build-ins in JS. ;)) (of course excluted the other 5 build-in constructors. (String, Array, Object, Function, Number)) – Andreas Louv Feb 24 '15 at 17:33
  • No idea what you're saying, @null. – ELLIOTTCABLE Mar 10 '15 at 09:47
  • @dev-null all JS constructors are functions - what matters is whether they also permit themselves to be called without `new` or not. `Boolean` does, as do the other standard types, but typically a browser's DOM functions do not. – Alnitak Nov 23 '15 at 11:55
  • 1
    Will fail both if there is value 0 in the array – Sai Ram Jan 31 '17 at 06:13
138

If you've got Javascript 1.6 or later you can use Array.filter using a trivial return true callback function, e.g.:

arr = arr.filter(function() { return true; });

since .filter automatically skips missing elements in the original array.

The MDN page linked above also contains a nice error-checking version of filter that can be used in JavaScript interpreters that don't support the official version.

Note that this will not remove null entries nor entries with an explicit undefined value, but the OP specifically requested "missing" entries.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • You're right! It can be so simple as this (and works!): test3 = [1,2,,3,,3,,,,7,,,7,,,0,,,4,,4,,5,,6,,undefined,,null,,]; printp( "Using array's native filtering: ", test3.filter( function(value){return (value==undefined) ? 0 : 1;} ) ); – Joe Pineda Nov 11 '08 at 18:02
  • Yeah, it works - but not all browsers have JavaScript 1.6, so it's only that good. – Jason Bunting Nov 11 '08 at 22:23
  • 3
    +1 As Alnitak said, they have the code that can be used in the case of not having js 1.6 available – Sameer Alibhai Apr 28 '10 at 18:50
  • Yes, won't work. Seems that as long as it's not undefined, it's true. – sqram Jul 10 '14 at 07:45
  • 3
    @katsh I've clarified - the code above _does_ work to remove entries for which no value exists at all, which (I've subsequently) learnt is semantically different to the case of a key that exists but which has `undefined` as its given value. – Alnitak Jul 10 '14 at 07:56
  • 4
    To remove undefined or null entries, just make a small modification... arr = arr.filter(function(v) { return v; }); – Alan CN Oct 06 '16 at 21:13
  • 6
    @AlanCN you've completely missed my point. The OP asked to remove _missing_ entries, whilst the bulk of the answers here (incorrectly) remove any "falsey" entries. – Alnitak Oct 07 '16 at 09:28
112

For removing holes, you should use

arr.filter(() => true)
arr.flat(0) // New in ES2019

For removing hole, null, and, undefined:

arr.filter(x => x != null)

For removing hole, and, falsy (null, undefined, 0, -0, 0n, NaN, "", false, document.all) values:

arr.filter(x => x)

arr = [, null, (void 0), 0, -0, 0n, NaN, false, '', 42];
console.log(arr.filter(() => true)); // [null, (void 0), 0, -0, 0n, NaN, false, '', 42]
console.log(arr.filter(x => x != null)); // [0, -0, 0n, NaN, false, "", 42]
console.log(arr.filter(x => x)); // [42]

Note:

  • Holes are some array indexes without elements.
arr = [, ,];
console.log(arr[0], 0 in arr, arr.length); // undefined, false, 2; arr[0] is a hole
arr[42] = 42;
console.log(arr[10], 10 in arr, arr.length); // undefined, false, 43; arr[10] is a hole

arr1 = [1, 2, 3];
arr1[0] = (void 0);
console.log(arr1[0], 0 in arr1); // undefined, true; a[0] is undefined, not a hole

arr2 = [1, 2, 3];
delete arr2[0]; // NEVER do this please
console.log(arr2[0], 0 in arr2, arr2.length); // undefined, false; a[0] is a hole
  • All above methods are returning a copy of the given array, not modifying it in-place.
arr = [1, 3, null, 4];
filtered = arr.filter(x => x != null);
console.log(filtered); // [1, 3, 4]
console.log(arr); // [1, 3, null, 4]; not modified
tsh
  • 4,263
  • 5
  • 28
  • 47
60

The clean way to do it.

var arr = [0,1,2,"Thomas","false",false,true,null,3,4,undefined,5,"end"];
arr = arr.filter(Boolean);
// [1, 2, "Thomas", "false", true, 3, 4, 5, "end"]
Tomás Senart
  • 1,403
  • 1
  • 12
  • 15
51

Actually, you can use ES6+ methods, assume the array is below:

const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];

And the answer could be one of these two ways:

  • First way:

    const clearArray = arr.filter(i => i); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
    
  • Second way:

    const clearArray = arr.filter(Boolean); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
    

Update 14th Oct 2022:

Those two answers aren't utterly correct, even in the given example, yeah, it works but pay attention to the number 0 in the given array, by both ways number zero is disappeared and it's obviously related to checking items by using boolean coercion.

A completely correct way is to check nulish and remove them:

const notNil = (i) => !(typeof i === 'undefined' || i === null);

const clearArray = arr.filter(i => isNil(i));

const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];
const notNil = (i) => !(typeof i === 'undefined' || i === null);

console.log("Not nil: ", arr.filter(notNil));
AmerllicA
  • 29,059
  • 15
  • 130
  • 154
  • Would `arr.filter(i) => typeof i === 'number';` produce the same result? – iiminov Oct 18 '22 at 08:45
  • Dear @iiminov, Why did you preassume the array items are `number`? They could be anything, the primary purpose is to wipe all `Nil` things. – AmerllicA Oct 18 '22 at 08:53
  • Sorry @AmerllicA, I wasn't assuming anything. All I wanted from the array are the numbers. So as per example array, I should be able to filter directly by type to obtain the same result. Of course, if I wanted to keep everything except null and undefined then I would filter accordingly. – iiminov Oct 19 '22 at 09:56
43

ES6:

let newArr = arr.filter(e => e);
deadcoder0904
  • 7,232
  • 12
  • 66
  • 163
Kanan Farzali
  • 991
  • 13
  • 23
42

Simple ES6

['a','b','',,,'w','b'].filter(v => v);
j08691
  • 204,283
  • 31
  • 260
  • 272
ML13
  • 895
  • 8
  • 15
  • 2
    This does not work: `[1, 'two', null, undefined, , NaN, false, true, 0].filter(v => v)`. – zipper Oct 03 '19 at 03:52
  • [1, 'two', null, undefined, , NaN, false, true, 0].filter(v => v!=null) preserves NaN and false. – Julian Oct 02 '21 at 07:17
22

With Underscore/Lodash:

General use case:

_.without(array, emptyVal, otherEmptyVal);
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);

With empties:

_.without(['foo', 'bar', '', 'baz', '', '', 'foobar'], '');
--> ["foo", "bar", "baz", "foobar"]

See lodash documentation for without.

Yves M.
  • 29,855
  • 23
  • 108
  • 144
c4urself
  • 4,207
  • 21
  • 32
16

If using a library is an option I know underscore.js has a function called compact() http://documentcloud.github.com/underscore/ it also has several other useful functions related to arrays and collections.

Here is an excerpt from their documentation:

_.compact(array)

Returns a copy of the array with all falsy values removed. In JavaScript, false, null, 0, "", undefined and NaN are all falsy.

_.compact([0, 1, false, 2, '', 3]);

=> [1, 2, 3]

Luis Perez
  • 27,650
  • 10
  • 79
  • 80
15

@Alnitak

Actually Array.filter works on all browsers if you add some extra code. See below.

var array = ["","one",0,"",null,0,1,2,4,"two"];

function isempty(x){
if(x!=="")
    return true;
}
var res = array.filter(isempty);
document.writeln(res.toJSONString());
// gives: ["one",0,null,0,1,2,4,"two"]  

This is the code you need to add for IE, but filter and Functional programmingis worth is imo.

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}
Erik Johansson
  • 323
  • 1
  • 5
  • 15
  • This should be the accepted answer, as it works out of the box. Thanks very much. – Tony Aug 06 '14 at 21:44
  • 2
    @Tony no, it shouldn't, because an element with an empty string in it is not the same as an "empty element", the latter being what the OP asked for. – Alnitak Feb 24 '15 at 17:18
14

Since nobody else mentioned it and most people have underscore included in their project you can also use _.without(array, *values);.

_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]
Josh Bedo
  • 3,410
  • 3
  • 21
  • 33
13

To remove undefined elements from an array you can simply use

const array = [
  { name: "tim", age: 1 },
  undefined,
  { name: "ewrfer", age: 22 },
  { name: "3tf5gh", age: 56 },
  null,
  { name: "kygm", age: 19 },
  undefined,
];
console.log(array.filter(Boolean));
DarckBlezzer
  • 4,578
  • 1
  • 41
  • 51
user3328281
  • 204
  • 3
  • 9
10
foo = [0, 1, 2, "", , false, 3, "four", null]

foo.filter(e => e === 0 ? true : e)

returns

[0, 1, 2, 3, "four"]

If you're positive you won't have any 0's in your array, it can look a bit nicer:

foo.filter(e => e)
sqram
  • 7,069
  • 8
  • 48
  • 66
8

You may find it easier to loop over your array and build a new array out of the items you want to keep from the array than by trying to loop and splice as has been suggested, since modifying the length of the array while it is being looped over can introduce problems.

You could do something like this:

function removeFalsyElementsFromArray(someArray) {
    var newArray = [];
    for(var index = 0; index < someArray.length; index++) {
        if(someArray[index]) {
            newArray.push(someArray[index]);
        }
    }
    return newArray;
}

Actually here is a more generic solution:

function removeElementsFromArray(someArray, filter) {
    var newArray = [];
    for(var index = 0; index < someArray.length; index++) {
        if(filter(someArray[index]) == false) {
            newArray.push(someArray[index]);
        }
    }
    return newArray;
}

// then provide one or more filter functions that will 
// filter out the elements based on some condition:
function isNullOrUndefined(item) {
    return (item == null || typeof(item) == "undefined");
}

// then call the function like this:
var myArray = [1,2,,3,,3,,,,,,4,,4,,5,,6,,,,];
var results = removeElementsFromArray(myArray, isNullOrUndefined);

// results == [1,2,3,3,4,4,5,6]

You get the idea - you could then have other types of filter functions. Probably more than you need, but I was feeling generous... ;)

Jason Bunting
  • 58,249
  • 14
  • 102
  • 93
6

What about this(ES6) : To remove Falsy value from an array.

var arr = [0,1,2,"test","false",false,true,null,3,4,undefined,5,"end"];

arr.filter((v) => (!!(v)==true));

//output:

//[1, 2, "test", "false", true, 3, 4, 5, "end"]
VIJAY P
  • 1,363
  • 1
  • 12
  • 14
6

You should use filter to get array without empty elements. Example on ES6

const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);
Gapur Kassym
  • 1,131
  • 12
  • 10
4

When using the highest voted answer above, first example, i was getting individual characters for string lengths greater than 1. Below is my solution for that problem.

var stringObject = ["", "some string yay", "", "", "Other string yay"];
stringObject = stringObject.filter(function(n){ return n.length > 0});

Instead of not returning if undefined, we return if length is greater than 0. Hope that helps somebody out there.

Returns

["some string yay", "Other string yay"]
Goku Nymbus
  • 571
  • 2
  • 11
  • +1 as this is very practical and exactly what I usually need working with string arrays, but be aware that this removes numbers (if they aren't in string form) since they don't have a .lenghth so, `["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123` Replacing that function... with String, ironically, leaves numbers in but would give the same result in your given array. – aamarks Apr 24 '18 at 15:45
3

I'm simply adding my voice to the above “call ES5's Array..filter() with a global constructor” golf-hack, but I suggest using Object instead of String, Boolean, or Number as suggested above.

Specifically, ES5's filter() already doesn't trigger for undefined elements within the array; so a function that universally returns true, which returns all elements filter() hits, will necessarily only return non-undefined elements:

> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(function(){return true})
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]

However, writing out ...(function(){return true;}) is longer than writing ...(Object); and the return-value of the Object constructor will be, under any circumstances, some sort of object. Unlike the primitive-boxing-constructors suggested above, no possible object-value is falsey, and thus in a boolean setting, Object is a short-hand for function(){return true}.

> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(Object)
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]
ELLIOTTCABLE
  • 17,185
  • 12
  • 62
  • 78
  • 1
    BEWARE: filter(String) and filter(Object) do not filter out null or numbers. Because a constructor is also a function you can pass String to filter i.e. `someArray.filter(String);` is actually equivalent to `someArray.filter(function(x){ return String(x); });`. If you want to remove all falsy values `someArray.filter(Boolean);` works to remove 0, -0, NaN, false, '', null, and undefined. – robocat Mar 12 '13 at 01:07
  • 1
    Nice answer, although I wonder about the performance overhead of calling the `Object` constructor as opposed to the `return true` method. @robocat the OP asked for empty elements to be removed, not nulls. – Alnitak Feb 24 '15 at 17:22
  • I prefer the shortest, and clearest, solution, except in tight-loops. Personal preference, I suppose. (= – ELLIOTTCABLE Feb 24 '15 at 17:24
3
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })

console.log(r) 

[1,2,3]

KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
3

Removing all empty elements

If an array contains empty Objects, Arrays, and Strings alongside other empty elements, we can remove them with:

const arr = [ [], ['not', 'empty'], {}, { key: 'value' }, 0, 1, null, 2, "", "here", " ", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ]

let filtered = JSON.stringify(
  arr.filter((obj) => {
    return ![null, undefined, ''].includes(obj)
  }).filter((el) => {
    return typeof el != "object" || Object.keys(el).length > 0
  })
)

console.log(JSON.parse(filtered))

Simple compacting (removing empty elements from an array)

With ES6:

const arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]

let filtered = arr.filter((obj) => { return ![null, undefined].includes(obj) })

console.log(filtered)

With plain Javascript ->

var arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]

var filtered = arr.filter(function (obj) { return ![null, undefined].includes(obj) })

console.log(filtered)
Zalom
  • 696
  • 9
  • 18
3

You can use filter with index and in operator

let a = [1,,2,,,3];
let b = a.filter((x,i)=> i in a);

console.log({a,b});
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
  • presuming that the array contains index numbers...? – Magne Nov 29 '20 at 17:34
  • @Magne in JS standard arrays indexes are numbers. The JS objects can contains other keys than numbers. JS arrays are also object and you can put key-value pair to it e.g `let a=[]; a.abc=1` - but usually no body do it (It is quite exotic to do it - because instead arrays you can just use e.g. object `{}`). And when you use array in so exotic way then standard JS array methods like `map`, `filter` etc. will ignore such key-value pairs - my solution based on `filter` and ignore it too. It is quite obvious that OP ask about standard JS array (because he not mention about such exotic use-case) – Kamil Kiełczewski Nov 29 '20 at 18:45
  • yeah, I was not referring to that, actually, but thanks for clarifying that too. I skimmed the top of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in and confusingly believe the `in` operator returned the value in the array. So I thought it would only work if the values in the array was the same as the index numbers one wanted to filter for. But I see now `in` refers to the properties (like indexes), not values, of an array. – Magne Dec 01 '20 at 13:23
  • SO didn't allow me to change my vote. :( If you make a small edit, then I can change my vote. – Magne Dec 01 '20 at 17:34
  • Why is this necessary? `.filter()` will skip over empty slots in the array, so `a.filter((x,i)=> i in a);` will *only* check existing elements. And it's implicit that an existing element's index exists in the array. So, it simplifies to `a.filter(() => true);` [few](https://stackoverflow.com/a/281335/) [other](https://stackoverflow.com/a/281393/) [answers](https://stackoverflow.com/a/48163228/) [here](https://stackoverflow.com/a/13587612/) already show this approach. – VLAZ Apr 22 '21 at 17:22
2

Another way to do it is to take advantage of the length property of the array : pack the non-null items on the 'left' of the array, then reduce the length. It is an in-place algorithm -does not allocates memory, too bad for the garbage collector-, and it has very good best/average/worst case behaviour.

This solution, compared to others here, is between 2 to 50 times faster on Chrome, and 5 to 50 times faster on Firefox, as you might see here : http://jsperf.com/remove-null-items-from-array

The code below adds the non-enumerable 'removeNull' method to the Array, which returns 'this' for daisy-chaining :

var removeNull = function() {
    var nullCount = 0           ;
    var length    = this.length ;
    for (var i=0, len=this.length; i<len; i++) { if (!this[i]) {nullCount++} }
    // no item is null
    if (!nullCount) { return this}
    // all items are null
    if (nullCount == length) { this.length = 0; return this }
    // mix of null // non-null
    var idest=0, isrc=length-1;
    length -= nullCount ;                
    while (true) {
         // find a non null (source) slot on the right
         while (!this[isrc])  { isrc--; nullCount--; } 
         if    (!nullCount) { break }       // break if found all null
         // find one null slot on the left (destination)
         while ( this[idest]) { idest++  }  
         // perform copy
         this[idest]=this[isrc];
         if (!(--nullCount)) {break}
         idest++;  isrc --; 
    }
    this.length=length; 
    return this;
};  

Object.defineProperty(Array.prototype, 'removeNull', 
                { value : removeNull, writable : true, configurable : true } ) ;
GameAlchemist
  • 18,995
  • 7
  • 36
  • 59
  • Nice answer, although it would be good to see some test cases to show it in action! – Alnitak Feb 24 '15 at 17:27
  • 2
    This answer is very fascinating but kind of reminds me of looking at a computer built in 1945 when I have a smartphone: `arr.filter(e => e)`. – agm1984 Sep 08 '17 at 05:07
  • @agm1984 your smartphone isn't smart – Hernán Eche Jun 04 '20 at 15:45
  • That may depend on your definition of `smart`--such as the verb, to cause a sharp stinging pain. This is relevant due to the physical pain if I weaponize my phone due to your comment. – agm1984 Jun 04 '20 at 15:57
2

What about that:

js> [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,].filter(String).join(',')
1,2,3,3,0,4,4,5,6
JessyNinja
  • 153
  • 1
  • 5
2

None of the answers above works best for all types. The below solution will remove null, undefined, {} [], NaN and will preserve date string and what's best is it removes even from nested objects.

function removeNil(obj) {
    // recursively remove null and undefined from nested object too.
    return JSON.parse(JSON.stringify(obj), (k,v) => {
      if(v === null || v === '') return undefined;
      // convert date string to date.
      if (typeof v === "string" && /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ$/.test(v))
        return new Date(v);
      // remove empty array and object.
      if(typeof v === 'object' && !Object.keys(v).length) return undefined;
      return v;
    });
  }

function removeNil(obj) {
    // recursively remove null and undefined from nested object too.
    return JSON.parse(JSON.stringify(obj), (k,v) => {
      if(v === null || v === '') return undefined;
      // convert date string to date.
      if (typeof v === "string" && /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ$/.test(v))
        return new Date(v);
      // remove empty array and object.
      if(typeof v === 'object' && !Object.keys(v).length) return undefined;
      return v;
    });
  }
  
 const ob = {
  s: 'a',
  b: 43,
  countries: [ 'a', 'b', 'c' ],
  l: null,
  n: { ks: 'a', efe: null, ce: '' },
  d: new Date(),
  nan: NaN,
  k: undefined,
  emptyO: {},
  emptyArr: [],
 }
 
 const output = removeNil(ob);
 
 console.log(output);
 console.log('Tests: ', ob.countries.length, typeof(ob.d))
Ashish Rawat
  • 3,363
  • 5
  • 29
  • 35
1

This works, I tested it in AppJet (you can copy-paste the code on its IDE and press "reload" to see it work, don't need to create an account)

/* appjet:version 0.1 */
function Joes_remove(someArray) {
    var newArray = [];
    var element;
    for( element in someArray){
        if(someArray[element]!=undefined ) {
            newArray.push(someArray[element]);
        }
    }
    return newArray;
}

var myArray2 = [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,];

print("Original array:", myArray2);
print("Clenased array:", Joes_remove(myArray2) );
/*
Returns: [1,2,3,3,0,4,4,5,6]
*/
Joe Pineda
  • 5,521
  • 3
  • 31
  • 40
  • 1
    This only appears to work "by accident", since it's the act of enumerating the keys via `for ... in` that actually causes the skipping of missing elements. The test for `undefined` only serves to remove real elements that are explicitly set to that value. – Alnitak Dec 29 '15 at 11:28
1

'Misusing' the for ... in (object-member) loop. => Only truthy values appear in the body of the loop.

// --- Example ----------
var field = [];

field[0] = 'One';
field[1] = 1;
field[3] = true;
field[5] = 43.68;
field[7] = 'theLastElement';
// --- Example ----------

var originalLength;

// Store the length of the array.
originalLength = field.length;

for (var i in field) {
  // Attach the truthy values upon the end of the array. 
  field.push(field[i]);
}

// Delete the original range within the array so that
// only the new elements are preserved.
field.splice(0, originalLength);
cluster1
  • 4,968
  • 6
  • 32
  • 49
  • the code is right, the comment is wrong. The act of using `for ... in` is what removes the undefined keys from the array, but you've actually no code here to otherwise accept only "truthy" values – Alnitak Jan 15 '18 at 10:45
1

This might help you : https://lodash.com/docs/4.17.4#remove

var details = [
            {
                reference: 'ref-1',
                description: 'desc-1',
                price: 1
            }, {
                reference: '',
                description: '',
                price: ''
            }, {
                reference: 'ref-2',
                description: 'desc-2',
                price: 200
            }, {
                reference: 'ref-3',
                description: 'desc-3',
                price: 3
            }, {
                reference: '',
                description: '',
                price: ''
            }
        ];

        scope.removeEmptyDetails(details);
        expect(details.length).toEqual(3);

scope.removeEmptyDetails = function(details){
            _.remove(details, function(detail){
                return (_.isEmpty(detail.reference) && _.isEmpty(detail.description) && _.isEmpty(detail.price));
            });
        };
Sandeep M
  • 248
  • 3
  • 6
1
var data= { 
    myAction: function(array){
        return array.filter(function(el){
           return (el !== (undefined || null || ''));
        }).join(" ");
    }
}; 
var string = data.myAction(["I", "am","", "working", "", "on","", "nodejs", "" ]);
console.log(string);

Output:

I am working on nodejs

It will remove empty element from array and display other element.

GGO
  • 2,678
  • 4
  • 20
  • 42
Jitendra virani
  • 366
  • 4
  • 8
1

All the empty elements can be removed from an array by simply by using array.filter(String); It returns all non empty elements of an array in javascript

Bhupesh Kumar
  • 240
  • 2
  • 14
  • 1
    Sadly it accepts `null` while using `Boolean` removes it an empty strings. – Paul Watson Jun 10 '20 at 14:18
  • 1
    @PaulWatson Yes unfortunately it accepts null as a string but can remove empty elements from array. Hope you understand – Bhupesh Kumar Jul 03 '20 at 07:35
  • It doesn't even work well. It's supposed to remove "non-empty elements" (supposedly, existing elements, dropping all empty slots) but it also filters out an empty string and empty arrays. f it's supposed to filter out *falsy* values then it actually leaves in `null` and `0`. Whichever way it's supposed to work it...doesn't. Especially if we consider anything that might have a custom `toString()` defined which can lead to further items considered falsy when they aren't. – VLAZ Apr 22 '21 at 17:35
1

Simplest way

[NaN, undefined, null, 0, 1, 2, 2000, Infinity].filter(Boolean)

Judith lobo
  • 131
  • 4
1

I do simply this way.

const arr = ['apple', '', 'orange', '', 'banana', ''];

const filteredArr = arr.filter(function(element) {
  return element !== '';
});

console.log(filteredArr); // ['apple', 'orange', 'banana']
Zia
  • 506
  • 3
  • 20
0

The best way to remove empty elements, is to use Array.prototype.filter(), as already mentioned in other answers.

Unfortunately, Array.prototype.filter() is not supported by IE<9. If you still need to support IE8 or an even older version of IE, you could use the following polyfill to add support for Array.prototype.filter() in these browsers :

if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun/*, thisArg*/) {
    'use strict';
    if (this === void 0 || this === null) {
      throw new TypeError();
    }
    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== 'function') {
      throw new TypeError();
    }
    var res = [];
    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++) {
      if (i in t) {
        var val = t[i];
        if (fun.call(thisArg, val, i, t)) {
          res.push(val);
        }
      }
    }
    return res;
  };
}
John Slegers
  • 45,213
  • 22
  • 199
  • 169
0

If anyone is looking for cleaning the whole Array or Object this might help.

var qwerty = {
    test1: null,
    test2: 'somestring',
    test3: 3,
    test4: {},
    test5: {
        foo: "bar"
    },
    test6: "",
    test7: undefined,
    test8: " ",
    test9: true,
    test10: [],
    test11: ["77","88"],
    test12: {
        foo: "foo",
        bar: {
            foo: "q",
            bar: {
                foo:4,
                bar:{}
            }
        },
        bob: {}
    }
}

var asdfg = [,,"", " ", "yyyy", 78, null, undefined,true, {}, {x:6}, [], [2,3,5]];

function clean_data(obj) {
    for (var key in obj) {
        // Delete null, undefined, "", " "
        if (obj[key] === null || obj[key] === undefined || obj[key] === "" || obj[key] === " ") {
            delete obj[key];
        }
        // Delete empty object
        // Note : typeof Array is also object
        if (typeof obj[key] === 'object' && Object.keys(obj[key]).length <= 0) {
            delete obj[key];
        }
        // If non empty object call function again
        if(typeof obj[key] === 'object'){
            clean_data(obj[key]);
        }
    }
    return obj;
}

var objData = clean_data(qwerty);
console.log(objData);
var arrayData = clean_data(asdfg);
console.log(arrayData);

Output:

Removes anything that is null, undefined, "", " ", empty object or empty array

jsfiddle here

Puni
  • 1,214
  • 2
  • 18
  • 34
0

This one will only remove empty values and not falsey ones, which I think is more desirable.

There is an option to also remove null values.

This method should be much faster than using splice.

    function cleanArray(a, removeNull) {
        var i, l, temp = [];
        l = a.length;
        if (removeNull) {
            for (i = 0; i < l; i++) {
                if (a[i] !== undefined && a[i] !== null) {
                    temp.push(a[i]);
                }
            }
        } else {
            for (i = 0; i < l; i++) {
                if (a[i] !== undefined) {
                    temp.push(a[i]);
                }
            }
        }
        a.length = 0;
        l = temp.length;
        for (i = 0; i < l; i++) {
            a[i] = temp[i];
        }
        temp.length = 0;
        return a;
    }
    var myArray = [1, 2, , 3, , 3, , , 0, , null, false, , NaN, '', 4, , 4, , 5, , 6, , , , ];
    cleanArray(myArray);
    myArray;
Trevor
  • 525
  • 2
  • 6
  • 19
0

use filter to remove empty string in array.

var s = [ '1,201,karthikeyan,K201,HELPER,karthikeyan.a@limitlessmobil.com,8248606269,7/14/2017,45680,TN-KAR24,8,800,1000,200,300,Karthikeyan,11/24/2017,Karthikeyan,11/24/2017,AVAILABLE\r',
  '' ]
var newArr = s.filter(function(entry) { return entry.trim() != ''; })

console.log(newArr); 
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
0

An in place solution:

function pack(arr) { // remove undefined values
  let p = -1
  for (let i = 0, len = arr.length; i < len; i++) {
    if (arr[i] !== undefined) { if (p >= 0) { arr[p] = arr[i]; p++ } }
    else if (p < 0) p = i
  }
  if (p >= 0) arr.length = p
  return arr
}

let a = [1, 2, 3, undefined, undefined, 4, 5, undefined, null]
console.log(JSON.stringify(a))
pack(a)
console.log(JSON.stringify(a))
bittnkr
  • 99
  • 10
0

If you're using NodeJS, you can use clean-deep package. Use npm i clean-deep before.

const cleanDeep = require('clean-deep');
var array = [0, 1, null, 2, "", 3, undefined, 3,,,,,, 4,, 4,, 5,, 6,,,,];
const filterd = cleanDeep(array);
console.log(filterd);
XDavidT
  • 147
  • 15
0

Most answers focus on creating a new array which is a copy of existing array with empty elements skipped.

But what if you actually want to remove empty elements from existing array? Most straightforward method is:

const some_array = [ 0, 1, undefined, "something", "", null, {}, , ]

for (let i = 0; i < some_array.length; ) {  // iterate some_array
  if (some_array[i] == null) {              // if empty
    some_array.splice(i, 1)                 // splice one element out of array
                                            // and do not advance to next element
                                            // (splice moves the next element to current position)
  } else {
    ++i                                     // else advance to next element
  }
}

Note the == null comparison which catches undefined, null and empty elements, but leaves 0 and "".

smokku
  • 1,256
  • 13
  • 22
-1

Filtering out invalid entries with a regular expression

array = array.filter(/\w/);
filter + regexp
Tobias
  • 4,999
  • 7
  • 34
  • 40
lcabral
  • 15
  • 1
  • 1
    Does this work? it shows an error *TypeError: [object RegExp] is not a function* – FreeLightman Aug 01 '16 at 15:33
  • @FreeLightman no, it doesn't. It's not even clear what is this supposed to do as the code is meaningless. Even if it was supposed to check if each item in the array matches a regex, that's going to filter out legitimate values like `"----"` (string with non-word characters). – VLAZ Apr 22 '21 at 17:39
-1

this is my solution for clean empty fields.

Start from fees object: get only avail attribute (with map) filter empty fields (with filter) parse results to integer (with map)

fees.map( ( e ) => e.avail ).filter( v => v!== '').map( i => parseInt( i ) );
Andrea Perdicchia
  • 2,786
  • 1
  • 20
  • 19
  • This doesn't seem to match the question at all? 1. A lot more operations that asked for 2. Seems to be targetting some very specific dataset 3. Doesn't even remove empty values. At best, it removes empty *strings*. – VLAZ Apr 22 '21 at 17:41
-1
var a = [{a1: 1, children: [{a1: 2}, undefined, {a1: 3}]}, undefined, {a1: 5}, undefined, {a1: 6}]
function removeNilItemInArray(arr) {
    if (!arr || !arr.length) return;
    for (let i = 0; i < arr.length; i++) {
        if (!arr[i]) {
            arr.splice(i , 1);
            continue;
        }
        removeNilItemInArray(arr[i].children);
    }
}
var b = a;
removeNilItemInArray(a);
// Always keep this memory zone
console.log(b);
Trung
  • 1,819
  • 1
  • 13
  • 10
-2

Nice ... very nice We can also replace all array values like this

Array.prototype.ReplaceAllValues = function(OldValue,newValue)
{
    for( var i = 0; i < this.length; i++ )  
    {
        if( this[i] == OldValue )       
        {
            this[i] = newValue;
        }
    }
};
A. Zalonis
  • 1,599
  • 6
  • 26
  • 41
-2

Here is an example using variadic behavior & ES2015 fat arrow expression:

Array.prototype.clean = function() {
  var args = [].slice.call(arguments);
  return this.filter(item => args.indexOf(item) === -1);
};

// Usage
var arr = ["", undefined, 3, "yes", undefined, undefined, ""];
arr.clean(undefined); // ["", 3, "yes", ""];
arr.clean(undefined, ""); // [3, "yes"];
rpearce
  • 1,720
  • 1
  • 21
  • 29
-3

I needed to do this same task and came upon this thread. I ended up using the array "join" to create a string using a "_" separator, then doing a bit of regex to:-

1. replace "__" or more with just one "_",
2. replace preceding "_" with nothing "" and similarly 
3. replace and ending "_" with nothing ""

...then using array "split" to make a cleaned-up array:-

var myArr = new Array("","","a","b","","c","","","","","","","","","e","");
var myStr = "";

myStr = myArr.join("_");

myStr = myStr.replace(new RegExp(/__*/g),"_");
myStr = myStr.replace(new RegExp(/^_/i),"");
myStr = myStr.replace(new RegExp(/_$/i),"");
myArr = myStr.split("_");

alert("myArr=" + myArr.join(","));

...or in 1 line of code:-

var myArr = new Array("","","a","b","","c","","","","","","","","","e","");

myArr = myArr.join("_").replace(new RegExp(/__*/g),"_").replace(new RegExp(/^_/i),"").replace(new RegExp(/_$/i),"").split("_");

alert("myArr=" + myArr.join(","));

...or, extending the Array object :-

Array.prototype.clean = function() {
  return this.join("_").replace(new RegExp(/__*/g),"_").replace(new RegExp(/^_/i),"").replace(new RegExp(/_$/i),"").split("_");
};

var myArr = new Array("","","a","b","","c","","","","","","","","","e","");

alert("myArr=" + myArr.clean().join(","));
Jason
  • 719
  • 9
  • 19
-4

This is another way to do it:

var arr = ["a", "b", undefined, undefined, "e", undefined, "g", undefined, "i", "", "k"]
var cleanArr = arr.join('.').split(/\.+/);
Nico Napoli
  • 1,867
  • 2
  • 13
  • 12
  • 1
    This is a really bad idea.. What if one of the values is "a.string.with.dots"? It would be broken into pieces when creating the new array... – Tim Baas May 19 '15 at 07:25
  • It's up to you what character you choose for join/split, you don't need to use a dot if you have a.string.with.dots – Nico Napoli May 19 '15 at 17:42
  • 1
    @BogdanGersak What if you cannot guarantee at design time whether the string is going to contain, or not contain, any specific character? – Synoli Dec 18 '15 at 17:42
-5

Try this. Pass it your array and it will return with empty elements removed. *Updated to address the bug pointed out by Jason

function removeEmptyElem(ary) {
    for (var i = ary.length - 1; i >= 0; i--) {
        if (ary[i] == undefined)  {
            ary.splice(i, 1);
        }       
    }
    return ary;
}
blurfus
  • 13,485
  • 8
  • 55
  • 61
Matty
  • 1,973
  • 4
  • 25
  • 29
-5

How about doing it this way

// Removes all falsy values 
arr = arr.filter(function(array_val) { // creates an anonymous filter func
    var x = Boolean(array_val); // checks if val is null
    return x == true; // returns val to array if not null
  });
lambda07
  • 21
  • 3