Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

In Java you can use a for() loop to go through objects in an array like so:

String[] myStringArray = {"Hello","World"};
for(String s : myStringArray)
{
    //Do something
}

can you do the same in JavaScript?

share|improve this question
1  
Ok, so I'm a bit confused, it's ok to use the enhanced for loop when you are accessing the objects? And use a sequential one for filling one? Is this correct? – Mark Szymanski Jun 10 '10 at 0:15
4  
no, it's really simple, array objects have numeric indexes, so you want to iterate over those indexes in the numeric order, a sequential loop ensures that, the enhanced for-in loop enumerates object properties, without an specific order, and it also enumerates inherited properties... for iterating over arrays sequential loops are always recommended... – CMS Jun 10 '10 at 0:38
related - stackoverflow.com/questions/5349425/… – jondavidjohn Nov 1 '11 at 17:53
1  
Any chance you could consider switching your accepted answer for this question? The community thinks that CMS' answer is superior to the one that solved your problem. Thanks. – Gray Apr 10 '12 at 13:18
2  
This question and answers are in woeful need of cleanup & clarification. – Kzqai Apr 12 '12 at 12:49
show 1 more comment

13 Answers

Use a sequential for loop:

var myStringArray = ["Hello","World"];
for (var i = 0; i < myStringArray.length; i++) {
    alert(myStringArray[i]);
    //Do something
}

@zipcodeman suggests the use of the for...in statement, but for iterating arrays for-in should be avoided, that statement is meant to enumerate object properties.

It shouldn't be used for array-like objects because:

  • The order of iteration is not guaranteed, the array indexes may not visited in the numeric order.
  • Inherited properties are also enumerated.

The second point is can give you a lot of problems, for example, if you extend the Array.prototype object to include a method there, that property will be also enumerated.

For example:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
  alert(array[i]);
}

The above code will alert, "a", "b", "c" and "foo!".

That be particularly a problem if you use some library that relies heavily on native prototypes augmention (such as MooTools for example).

The for-in statement as I said before is there to enumerate object properties, for example:

var obj = {
  "a": 1,
  "b": 2,
  "c": 3
};

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) { 
  // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
    alert("prop: " + prop + " value: " + obj[prop])
  }
}

In the above example the hasOwnProperty method allows you to enumerate only own properties, that's it, only the properties that the object physically has, no inherited properties.

I would recommend you to read the following article:

share|improve this answer
22  
Why the down-vote? for...in should be avoided for Array-like objects! – CMS Jun 10 '10 at 0:10
4  
This is the reason ( by CMS him self ) stackoverflow.com/questions/1885317/… – OscarRyz Jun 10 '10 at 0:13
5  
+1 for adding explanation why not to use for( in ) – OscarRyz Jun 10 '10 at 0:24
12  
please cache the length of the array in your answer – Gabriel May 16 '11 at 22:52
3  
@DoubleGras, I think that is an opinion that is not shared by everyone. See: stackoverflow.com/questions/5752906/… or groups.google.com/forum/?fromgroups#!topic/jsmentors/… – Matthijs Wessels Aug 14 '12 at 16:41
show 8 more comments

I did not yet see this variation, which I personally like the best:

Given an array:

var someArray = ["some", "example", "array"];

You can loop over it without ever accessing the length property:

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

See this JsFiddle demonstrating that: http://jsfiddle.net/prvzk/

This only works for arrays that are not sparse. Meaning that there actually is a value at each index in the array. However, I found that in practice I hardly ever use sparse arrays in Javascript... In such cases it's usually a lot easier to use an object as a map/hashtable. If you do have a sparse array, and want to loop over 0 .. length-1, you need the for (var i=0; i<someArray.length; ++i) construct, but you still need an if inside the loop to check whether the element at the current index is actually defined.

Also, as CMS mentions in a comment below, you can only use this on arrays that don't contain any falsish values. The array of strings from the example works, but if you have empty strings, or numbers that are 0 or NaN, etc. the loop will break off prematurely. Again in practice this is hardly ever a problem for me, but it is something to keep in mind, which makes this a loop to think about before you use it... That may disqualify it for some people :)

What I like about this loop is:

  • It's short to write
  • No need to access (let alone cache) the length property
  • The item to access is automatically defined within the loop body under the name you pick.
  • Combines very naturally with array.push and array.splice to use arrays like lists/stacks

The reason this works is that the array specification mandates that when you read an item from an index >= the array's length, it will return undefined. When you write to such a location it will actually update the length.

For me, this construct most closely emulates the Java 5 syntax that I love:

for (String item : someArray) {
}

... with the added benefit of also knowing about the current index inside the loop

share|improve this answer
2  
Notice that with this approach the loop will stop as soon it finds a falsey value, such as an empty string, 0, false, NaN, null or undefined, even before i reaches the length, e.g.: jsfiddle.net/prvzk/1 – CMS Feb 28 at 18:31
Good point, that is true! – Stijn de Witt Mar 1 at 12:05
I incorporated your comment in the answer, thanks CMS! – Stijn de Witt Mar 1 at 12:15

If you're using the jQuery library, consider using http://api.jquery.com/jQuery.each/

From the documentation:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

Returns: Object

Description: A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties.

The $.each() function is not the same as $(selector).each(), which is used to iterate, exclusively, over a jQuery object. The $.each() function can be used to iterate over any collection, whether it is a map (JavaScript object) or an array. In the case of an array, the callback is passed an array index and a corresponding array value each time. (The value can also be accessed through the this keyword, but Javascript will always wrap the this value as an Object even if it is a simple string or number value.) The method returns its first argument, the object that was iterated.

share|improve this answer
1  
jQuery for everything? – Exception Feb 7 at 19:03
Agreed with Exception. Do not underestimate the impact of extra dependencies. I would advice against this except in code that is already heavily using jQuery anyway. – Stijn de Witt Mar 31 at 19:04

To directly answer the question: no, you can't. JavaScript does not have a concise syntax for iterating over Arrays. At least, not universally.

If you want code that is both efficient and universal (that is, it runs in all browsers and other js interpreters), you need to use an explicit counting loop. The safest version, which handles sparse arrays properly, is this:

var myStringArray = [ "Hello", "World" ]
var len = myStringArray.length
for (var i=0; i<len; ++i) {
  if (i in myStringArray) {
    var s = myStringArray[i];
    ... do something with s ...
  }
}

Assigning the length value to the local variable (as opposed to including the full myStringArray.length expression in the loop condition) can make a significant difference in performance; using Rhino on my machine, the speedup is 43%.

If you're willing to restrict yourself to a subset of available JavaScript engines, then you can use the enhanced looping method forEach, which takes a function that is called once per item in the array, and automatically handles sparse arrays properly:

var myStringArray = [ "Hello", "World" ]
myStringArray.forEach( function(s) { 
     ... do something with s ...
} )

The performance of forEach actually beats the explicit counting loop with a local length var by a factor of 2 in SpiderMonkey (again, on my machine). It's slower in Rhino, but only barely, while still being faster than the counting loop without the cache var.

The for...in syntax mentioned by others is for looping over an object's properties; since an Array in JavaScript is just an object with numeric property names (and a magical "length" property), you can theoretically loop over an Array with it. But the problem is that it doesn't restrict itself to the numeric property values, and in JavaScript, even methods are actually just properties whose value is a closure. Therefore, the for...in syntax should not be used for looping through Arrays. (It's not so great for generic Objects being used as maps/hashes/dictionaries, either, to be honest.)

share|improve this answer
1  
Note that some interpreters (e.g. V8) will automatically cache the length of the array if the code is called enough times and it detects that the length is not modified by the loop. While caching the length is still nice, it may not provide a speed boost when your code is being invoked enough times to actually make a difference. – Phrogz Jun 4 '12 at 16:29

If you want a terse way to write a fast loop and you can iterate in reverse:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

This has the benefit of caching the length (similar to for (var i=0,len=myArray.length;i<len;++i) and unlike for (var i=0;i<myArray.length;++i)) while being fewer characters to type.

There are even some times when you ought to iterate in reverse, such as when iterating over a live NodeList where you plan on removing items from the DOM during iteration.

share|improve this answer
It took me a while to figure out why it's written the way it's written, but now that I know I can truly say: this is ingenious. – TomTasche Jan 29 at 19:02
For the people that don't get what is so ingenious: The i-- expression is first evaluated and allows the loop to continue when it's not falsish... Afterwards the counter is decremented. As soon as i becomes zero it will break out of the loop as zero is a falsish value in Javascript. – Stijn de Witt Mar 1 at 12:09
1  
falsish? You mean falsey. Let's all stick the proper terminology to avoid confusion ;) – danwellman Apr 27 at 7:33

It's not 100% identical, but similar:

var myStringArray = ['Hello', 'World']; // array uses [] not {}
for (var i in myStringArray) {
    console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
}
share|improve this answer
It seems that this would run up against similar problems as other for in usages with an array object, in that prototype member variables would be caught by the for in as well. – Kzqai Apr 18 '12 at 15:34

I would thoroughly recommend making use of the underscore.js library. It provides you with various functions that you can use to iterate over arrays/collections.

For instance:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
share|improve this answer

There's a method to iterate over only own object properties, not including prototype's ones:

for (var i in array) if (array.hasOwnProperty(i)) {
    // do something with array[i]
}

but it still will iterate over custom-defined properties.

In javascript any custom property could be assigned to any object including array.

If one wants to iterate over sparsed array, for (var i = 0; i < array.length; i++) if (i in array) or array.forEach with es5shim should be used.

share|improve this answer

Can't beleive no one mentioned using the while loop...

var i=0,item,items = ['one','two','three'];
while(item=items[i++]){
    console.log(item);
}

logs: 'one','two','three'

and for the reverse order, an even more efficient loop

var items = ['one','two','three'], i=items.length;
while(i--){
    console.log(items[i]);
}

logs: 'three','two','one'

or the classical for loop

var items = ['one','two','three']
for(var i=0,l=items.length; i < l ; i++){
    console.log(items[i]);
}

logs: 'one','two','three'

reference: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/

share|improve this answer
4  
The first example of the "while" syntax won't work if any of the array elements is falsy. – QmunkE Apr 16 '12 at 14:42
@QmunkE yep, thanks for mentioning that. – Timo Huovinen Apr 16 '12 at 14:45
... and this while loop is equivalent to: for (var i=0,item; item=items[i]; i++) , which takes away the need to declare the index and item variables beforehand... – Stijn de Witt Mar 31 at 19:09

In JavaScript it's not advisable to loop through an Array with a for-in loop, but it's better using a for loop such as:

for(var i=0, len=myArray.length; i < len; i++){}

It's optimized as well ("caching" the array length). If you'd like to learn more, read my post on the subject.

share|improve this answer
2  
Straight forward, thanks. – Horst Walter Aug 19 '11 at 11:10
myArray.forEach(function(obj) {}); is still the best – Jannis Jan 2 '12 at 19:47
a tiny improvement: you could use ++i instead of i++ – roberkules Apr 12 '12 at 14:58
1  
++i is an old school optimization that modern compilers do for you in a for loop since a long time ago :) stackoverflow.com/a/1547433/1033348 – ngryman Apr 15 '12 at 0:45
@Jannis .forEach has several things against it. 1) not native 2) Requires a new execution context for EVERY index which is rather expensive and seems like overkill (see dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts) – Jose May 8 '12 at 13:03
show 1 more comment

ok, seriously do not use the method that includes looking up the length on each iteration.

var i = 0,
    item;
for ( ; item = myStringArray[i++] ; ){
  item; // this is the string at the index
}

or if you really want to get the id and have a really classical for loop:

var i = 0,
    len = myStringArray.length;

for ( ; i < len ; i++ ){
  myStringArray[i]; // don't use this if you plan on changing the length of the array
}
share|improve this answer
1  
Note that some interpreters (e.g. V8) will automatically cache the length of the array if the code is called enough times and it detects that the length is not modified by the loop. – Phrogz Jun 4 '12 at 16:28
Thanks for the info @Phrogz it's true that there is a lot of optimizations that the VM can make, but since older browsers don't have this it would still be best practice to optimize for it since it is so cheap. – Gabriel Jun 26 '12 at 1:43
@Gabriel: Why? Please give real-world examples showing that not caching the length is actually a performance bottleneck. I follow the 'premature optimization is the root of all evil' approach. I will fix that one loop that actually poses a problem once I encounter it... – Stijn de Witt Mar 31 at 19:06
@StijndeWitt imo it is just a stylistic issue. Honestly I no longer even use for loops instead relying on underscore for things like _.each, _.map etc. to do these things. When I did write loops like this I cached the length primarily so that all my variable declaration were in one place, at the top of my function. Following my advice in this regard is inconsequential to any real world application. Premature optimization is super bad, but if optimization happens to result from stylistic decisions I don't think it actually matters. – Gabriel Apr 4 at 17:15

Opera, Safari, Firefox and Chrome now all share a set of enhanced Array methods for optimizing many common loops.

You may not need all of them, but they can be very useful, or would be if every browser supported them.

The mozilla labs published the algorithms they and webkit both use, so that you can add them yourself.

filter returns an array of items that satisfy some condition or test.

every returns true if every array member passes the test.

some returns true if any pass the test.

forEach runs a function on each array member and doesn't return anything.

map is like forEach, but it returns an array of the results of the operation for each element.

These methods all take a function for their first argument, and have an optional second argument, which is an object whose scope you want to impose on the array members as they loop through the function.

Ignore it until you need it.

indexOf and lastIndexOf find the appropriate position of the first or last element that matches its argument exactly.

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this)) return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what) return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L) i= L-1;
            else if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what) return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this)) return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p]) ap[p]= p2[p];
    }
    return true;
})();
share|improve this answer
Useful, Thanks! – Timo Huovinen Mar 21 '12 at 11:09

You can use map (also known as apply in other languages like python, and probably haskell too)

[1,2,3,4].map( function(item) {
     alert(item);
})

The general syntax is:

array.map(func)

func should take one parameter.

The return value of array.map is another array, so you can use it like this:

var x = [1,2,3,4].map( function(item) { return item * 10; } );

And now x is [10,20,30,40]

EDIT:

I must clarify: this concept is from the functional paradigm.

You don't have to write the function inline; one might do so as a first sketch, but you could then extract it into its own function.

var item_processor = function(item) {
      // do something complicated to an item 
}

new_list = my_list.map(item_processor);

which would be sort-of equivalent to:

 for(item in my_list) { item_porcessor(item); }

except you don't get the new_list.

share|improve this answer
3  
No, but it can be more powerful. check this out: joelonsoftware.com/items/2006/08/01.html – hasen j Jun 10 '10 at 0:14
8  
That particular example is probably better implemented using Array.forEach. map is for generating a new array. – harto Jun 10 '10 at 0:20
6  
@hasen, the Array.prototype.map method is part of the ECMAScript 5th Edition Standard, is not yet available on all implementations (e.g. IE lacks of it), also for iterating over an array I think the Array.prototype.forEach method is more semantically correct... also please don't suggest the for-in statement, see my answer for more details :) – CMS Jun 10 '10 at 0:30
3  
aagh .. remind me again why I hate IE? – hasen j Jun 10 '10 at 0:31
1  
If you check out the link CMS provided, there's an implementation you can use in browsers that don't natively support it. – harto Jun 10 '10 at 4:42
show 8 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.