Easy loop for every element of an array

There’s something bugging me with javascript for loop : the extra work to loop though all elements of an array. Suppose I want to alert each element of an array, there are three ways of doing it.

First, you loop with an index and assign the element to a variable.

  1. var items = ["a", "b", "c"];
  2. for (var i = 0; i < items.length; i++) {
  3.   var item = items[i];
  4.   alert(item);
  5. }

You always have to have that extra assignment at the beginning of the loop.

Second, you loop with a for each.

  1. var items = ["a", "b", "c"];
  2. for (var i in items) {
  3.   var item = items[i];
  4.   alert(item)
  5. }

In javascript, the for each loops though the index of the array instead of looping though the elements, like in most other languages. Thus, you also have to make the extra assignment at the beginning of the loop.

The easiest way of doing it is the third one.

  1. var items = ["a", "b", "c"];
  2. for (var i = 0, item; item = items[i]; i++) {
  3.   alert(item);
  4. }

How does it work? First it uses multi-assignment on one line. In javascript, you could write var i = 0, j = 1; and it would create two variables, i and j.

The second part of the for is confusing : it assigns the item but it never check if i it is out of bounds of the array (using i < items.length). It works because when javascript tries to assign an item after the end of the array (in our case items[3]), it returns null which is considered by javascript as false.

Comments

  1. # Rob May 12, 2009 at 10:41:19

    Did you accidentally leave line #3 in the last example?
    I thought the point was to get rid of var item = items[i];

  2. # Rob May 12, 2009 at 10:44:12

    Just tried it, and it looks like a yes. This works fine:

    var items = ["a", "b", "c"];
    for (var i = 0, item; item = items[i]; i++) {
    alert(item);
    }

    Of if you wanted to lump it all together:
    for (var i = 0, item; item = ["a", "b", "c"][i]; i++) {
    alert(item);
    }

  3. # Femi May 12, 2009 at 10:49:15

    I’m not sure the real benefit here? Enlighten me if wrong.

    You are still manually assigning the variable. Your just doing it on the same line, which as you quite rightly pointed out makes the code fragment more confusing than it appears worth.

    For the above scenario, why not just use style 1 or 2 and alert(items[i])?

  4. # Dan (maintainer of Javascript Kata) May 12, 2009 at 10:56:43

    @Rob
    Sorry, my mistake. I edited the post.

    @Femi
    The variable is still manually assigned in the header of the loop, you can’t avoid it. In this simple case, it would have been easier to simply write alert(items[i]) but when you have more code than that, it’s confusing to always write it completly instead of its shorter version, item.

  5. # Robert Schultz May 12, 2009 at 11:45:25

    #3 fails when you have false or null as a value in the array:
    var items = ["a", "b", false, "c"];

    It’ll stop before it gets to “c”

    The first solution will correctly iterate over all of them.

  6. # Rick May 12, 2009 at 12:26:19

    Stick with method #1.

    #2 iterates over the array’s properties, which are not necessarily only its values. It should be avoided unless you have a good reason to do it this way.
    #3 fails for the reason Robert pointed out, and also for sparse arrays. For example:

    var items = ["a", "b", "c"];
    items[47] = “d”;

    items.length will return 48, so method #1 will find [47] without trouble. Method #3 will stop at [3], because it returns undefined.

  7. # Dan (maintainer of Javascript Kata) May 12, 2009 at 12:28:39

    @Yes, indeed. But you can write something like that : for (var i = 0, item; (item = items[i]) || i < items.length; i++).

    Things are getting out of control! ;)

  8. # Josh McDonald May 13, 2009 at 02:07:18

    Why not:

    for each (item in items)
    {
    alert(item);
    }

    Is any reasonable environment still stuck with JS < 1.6?

  9. # Tobias May 13, 2009 at 05:10:35

    @John

    Perhaps because it says: “Warning: Never use a loop like this on arrays” on https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Statements:for_each…in

    The ‘for (each) in’ loops over all the properties of an object. Not just the index of an array.

  10. # Stefano May 14, 2009 at 04:59:28

    var items = ["a", "b", "c"];
    for (var i = 0, l = items.length; i < l; alert(items[i++]) );
    // alert can be a lambda
    // pay attention to l = items.length … don’t modify the length of the array inside the loop because it’s read once before looping

    “for in” is not so safe…it loops on properties, so the array instance must be “pure array” to work correctly:

    Array.prototype.bar=”bar”;
    var items = ["a", "b", "c"];
    items.foo=’foo’;

    for (var p in items) {
    alert(items[p]);
    };
    //shows a, b, c, foo, bar

  11. # Binny V A May 14, 2009 at 15:13:55

    I wrote about the different types of For loops in JavaScript a while ago. I have also briefly touched on the optimization part of for loops.

  12. # Asnawi October 28, 2009 at 04:19:14

    If u have a false or null value in the array, u could use typeof like this:

    var items = ["a", "b", false, "c", null];
    for (var i = 0, item; typeof (item = items[i]) != ‘undefined’; i++) {
    alert(item);
    }

    but u still have problem if the array contains undefined value, like:

    var items = ["a", undefined, "b"];

  13. # Peter December 9, 2009 at 10:59:40

    The third way of doing it is just standard programming practice. It’s how I’ve always done it in JavaScript, C or any similar language!

Post a comment

Comments are moderated and innapropriate ones won't be approved. Please respect this public space.