Tutorial details:
Written by: Neil Webb (aka Mortimer Jazz) | www.nwebb.co.uk
Time: 40 Minutes
Difficulty Level: Intermediate
Requirements: Flash 5, Flash MX
Topics Covered: Nested Loops
Assumed knowledge: For-loops, Variables, Functions.

Download the fla containing these examples (zipped)

Most people know how to use loops, but surprisingly few people realize the power of nested loops. This tutorial aims to give you a solid understanding of how they work and ideas for how they can be used in your Flash movies. If you don't know how to use a for loop then read Jesse's tutorial on Scripted Loops first. That will get you up to speed. This tutorial should be especially useful as a precursor to beginning XML, but then loops are useful for pretty much anything!

So what's the big deal about nested loops then? Well, the big deal lies with the order in which they execute.
It makes for a very powerful way of sorting through data, by breaking it down in to smaller and smaller chunks, but first things first...
There are two common ways of writing nested loops. One way is to 'bury' loops inside each other like this:

//------nested loops-------
//outer loop
for (i=0; i<2; i++){
        trace("outerloop");
        //inner loop
        for(j=0; j<2; j++){
                trace("innerloop");
        }
}

The other, my personal preference for reasons of clarity, is to put each loop inside a function and call the second loop from inside the first loop - like so:

myLoop1();//call the first function

function myLoop1(){
        for(i=0; i<2; i++){
                trace("loop1");
                myLoop2();//call the second loop from within the first loop
        }
}

function myLoop2(){
        for(j=0; j<2; j++){
                trace("loop2");
        }
}

If you haven't done so already, copy and paste the second example into an empty frame in a new movie (or download the fla, and uncomment the first example), run the movie and let's have a look at what those traces sent to the output window...

Okay, this is the order we get: loop1, loop2, loop2, loop1, loop2, loop2

Notice the order in which the loops execute, it may not be as you expected.
Both loops are told to execute twice, so how come it didn't just go loop1, loop2, loop1, loop2 ?

Well, it's all about loops completing iterations. The word "iterate" simply means to "repeat in sequence". If we created a for-loop and told it to loop twice, we would say that it has two iterations...otherwise programmers would be talking about "the fourth loop of the second loop" and programming doesn't need to be made any more complicated thank you very much! If I talk about "The second iteration of the first loop" then it is so much clearer and you have a chance of understanding what I'm on about!

Loop1 can't finish it's first iteration until it's done everything inside of it. Loop2 is inside of it. Because loop2 doesn't call any other functions or have any nested-loops inside itself it just loops until it's completed as many iterations as it was told to do.

But wait! Loop1 was told to loop twice, and we're still on the first loop. Now that it's finished doing everything inside of it, it can complete it's first iteration and start on the second one. Now the whole process is repeated..... it executes loop2 again, which iterates twice, then loop1 ends. Phew!
Time for an example I think. Here is the same code I used before but now it's got a few added traces so we can see what's happening in our movie:

myLoop1();//call the first function

function myLoop1(){
        for(i=0; i<2; i++){
                trace("loop1");
                myLoop2();//call the second loop from within the first loop
                trace ("finished an iteration of loop 1");
        }
        trace ("finished loop 1");
}

function myLoop2(){
        for(j=0; j<2; j++){
                trace("loop2");
        }
        trace ("finished an iteration of loop 2");
}

Take a moment to study the trace output in the output window. That should make it a bit clearer. The first loop calls the second loop (okay, the first function calls the second function, but for the sake of clarity...). So where were we? Oh yes, the first loops calls the second loop. There are no more nestedloops after that so the second loop says "I'm going to loop as many times as I possibly can". When it's done that, the loop before it is checked again to see if it's finished looping too. If it's not then it loops a second time ...calls loop2 again and the whole process is repeated.
Now moving swiftly on, let's look at what happens when we create a third-loop/third-function and call it from within loop2, and then we'll look at a practical application for all this stuff. Yes of course there is a use. You think I'm doing this for fun?

myLoop1();//call the first function

function myLoop1(){
        for(i=0; i<2; i++){
                trace("loop1");
                myLoop2();//call the second loop from within the first loop
        }
        trace ("finished loop 1");
}

function myLoop2(){
        for(j=0; j<2; j++){
                trace("loop2");
                myLoop3();//call the second loop from within the first loop
        }
        trace ("finished loop 2");
}

function myLoop3(){
        for(p=0; p<2; p++){
                trace("loop3");
        }
        trace ("finished loop 3");
}

So in essence it goes: 1,2,3,3,2,3,3......1,2,3,3,2,3,3 etc.
That's all very well, but how is it useful to you? Okay, well a good real-world analogy is that of sorting out a deck of playing cards.
If someone asked you to take an ordinary pack of shuffled cards and then sort them in to suits, and then sort all of those suits in to numerical order you'd probably tell them exactly where they can stick their cards and wander off down the pub.