frequent
frequent

Reputation: 28513

How to set an empty array in a for loop in JavaScript in case the array to loop is undefined?

I want to loop over an array called children which may or may not be defined.

Currently I'm doing this:

var i;
var foo = {/*"children": ["1","2","3","4"]*/};


for (i = 0; i < [foo.children || []][0]. length; i += 1) {
   console.log("hello")
}

This works correctly, because in case children is undefined, [foo.children || []][0] ends up being [[]] whose first element is an empty array [].

Question:
Is there any way to leave away the outer array?

I don't want to use an if-clause testing for children, just modify the array.

One way would be:

for (i = 0; i < foo.children.length || [].length; i += 1) {
   console.log("hello")
}

but I'm looking for other alternatives if exist.

Thanks

EDIT: Here is a jsperf on all variants. Interesting...

Upvotes: 0

Views: 149

Answers (6)

user1636522
user1636522

Reputation:

Why not using a function to hide all these dirty statements?

function each(array, fn) {
    if (array) {
        var i = -1;
        while (++i < array.length) {
            if (fn(array[i]) === false) return;
        }
    }
}

Upvotes: 0

Tibos
Tibos

Reputation: 27833

EDIT: According to comments on other answers the OP wants terse, but jsLint appropriate code. Here it is:

var i, c, foo = {}, console; 

for (i = 0, c = foo.children; i < (c && c.length); i += 1) {
    console.log("hello");
}

I will leave the other possibilitis here for people who don't have as strict requirements as the OP does.


You can use the && operator:

for (i = 0; i < (foo && foo.children && foo.children.length); i += 1) {
   console.log("hello")
}

If there is a chance that foo is not defined at all, then you need something slightly worse:

for (i = 0; i < ((typeof foo === 'object') && foo.children && foo.children.length); i += 1) {
   console.log("hello")
}

Or if you're sure that foo is an object, you can skip the first check:

for (i = 0; i < (foo.children && foo.children.length); i += 1) {
   console.log("hello")
}

Upvotes: 1

dsteinhoefel
dsteinhoefel

Reputation: 706

You could add a condition checking the existence of the array to your for loop like this:

for (i = 0; (typeof foo.children != 'undefined') && (i < foo.children.length); i++) {
  // do something
}

/edit: OK, others were a bit faster than me, and foo.children is a nice alternative to typeof foo.children != 'undefined' ;)

Upvotes: 0

Syjin
Syjin

Reputation: 2810

Another possible way:

for (i = 0; foo.children && i < foo.children.length; i += 1)

Upvotes: 0

Bergi
Bergi

Reputation: 664969

Use parenthesis instead of that one-item-array:

for (i = 0; i < (foo.children || []).length; i += 1) {

or move it further outside:

for (i = 0; foo.children && i < foo.children.length; i += 1) {

which is very near to

if (foo.children) for (i = 0; i < foo.children.length; i += 1) {

which would indeed be the cleanest way. There's nothing wrong with an if-statement.

Upvotes: 2

Barmar
Barmar

Reputation: 781721

var len = foo.children ? foo.children.length : 0;
for (i = 0; i < len; i++) {
    ...
}

Upvotes: 3

Related Questions