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?
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?
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,,,,]);
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.
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:
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
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
Actually, you can use ES6+ methods, assume 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 ]
const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];
console.log("arr.filter(i => i)", arr.filter(i => i));
console.log("arr.filter(Boolean)", arr.filter(Boolean));
@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;
};
}
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));
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... ;)
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))
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)
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});
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
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))
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]
*/
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
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))
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);
Filtering out invalid entries with a regular expression
array = array.filter(/\w/);
filter + regexp
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 ) );
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);
// recursive implementation
function compact(arr) {
const compactArray = [];
//base case
if(!arr.length) return []
if(typeof arr[0] !== "undefined"
&& arr[0]!==null && arr[0] !== " " &&
arr[0]!== false &&
arr[0]!== 0){
compactArray.push(arr[0]);
}
return compactArray.concat(compact(arr.slice(1)))
}
compact([1,0,false,null,undefined,"banana"])`
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;
}