1663

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?

4
  • 28
    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. Commented Dec 29, 2015 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 nulls 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. Commented Aug 11, 2021 at 17:01
  • For long sparse arrays Array.filter does not help. See solution in the answer stackoverflow.com/questions/16196338/… Commented Mar 26, 2024 at 11:51
  • Interesting that none of the answers changes the existing array - they all create a new one (mostly using filter()). Any offers? Commented Oct 2, 2024 at 21:22

52 Answers 52

1
2
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]
*/
1
  • 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. Commented Dec 29, 2015 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);
1
  • 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 Commented Jan 15, 2018 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));
            });
        };
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.

2
  • output: 'I am working on nodejs'. it will remove empty element from array and display other element. Commented Feb 21, 2018 at 9:35
  • I improved your answer. Please try to make simple, clear and readable answer ;) Commented Feb 21, 2018 at 9:45
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;
  };
}
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

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;
0

use filter to remove empty string in array.

var s = [ '1,201,karthikeyan,K201,HELPER,[email protected],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); 

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))
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);
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 "".

0

A way with the standard cycle:

var a = [, , , 6, undefined, , 5, , null, 7];
for (var i = a.length - 1; i > -1; i--) {
    if (!(i in a)) a.splice(i, 1);
}

undefined and null are not removed as expected.

0

Using some cool binary operands, you could also do something like:

const capitalizeFirstLetter = (str) =>
  str ? String.fromCharCode(str.charCodeAt(0) & ~32) + str.slice(1) : '';

But this seems excessive.

-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 ) );
1
  • 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. Commented Apr 22, 2021 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);
-1

Filtering out invalid entries with a regular expression

array = array.filter(/\w/);
2
  • 1
    Does this work? it shows an error TypeError: [object RegExp] is not a function Commented Aug 1, 2016 at 15:33
  • 1
    @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). Commented Apr 22, 2021 at 17:39
-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"];
-2

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;
        }
    }
};
-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(","));
1
  • For string types this works, but it could get 'interesting' on a mixed-type array. Commented Sep 28, 2012 at 19:24
-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(/\.+/);
3
  • 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... Commented May 19, 2015 at 7: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 Commented May 19, 2015 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? Commented Dec 18, 2015 at 17:42
-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
  });
1
  • 1
    Please explain this a bit to help the other users. Commented Oct 26, 2016 at 14:53
-6

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;
}
5
  • 2
    DON'T use this function, it fails for obvious reasons: Try it on this array: var myArray = [1,2,,3,,3,,,,,,4,,4,,5,,6,,,,]; Commented Nov 11, 2008 at 16:03
  • Oh yes it is somewhat buggy. If you fix it I will accept your answer. Commented Nov 11, 2008 at 16:04
  • This has been updated and should no longer experience the same error Commented Nov 11, 2008 at 16:15
  • 3
    The iteration start with i=ary.length which is wrong. It should be i=ary.length-1 Commented Jun 5, 2009 at 13:45
  • Its still buggy. it starts with length and checks for array[i] which will be always undefined in first case. Commented Nov 8, 2011 at 22:15
1
2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.