Going loopy

Tags: 

Note: if you don't know about JavaScript objects, read this before proceeding.

When you want to do the same thing a bunch o' times, or almost the same thing a bunch o' times, use a loop.

An example. You're peeling potatoes. Lots of them. You have a sack of unpeeled potatoes, and a cooking pot. Here's a loop:

  1. While there are potatoes in the sack:
  2.     Take a potato from the sack.
  3.     Peal the potato.
  4.     Put the potato into the pot.

This loop does almost the same thing a bunch o' times. The text in yellow is the same every time. What is different? The potato. Line 2 gets a new potato. Lines 3 and 4 do something with that new potato.

The potato is a "looping variable." It changes each time through the loop. Lines 3 and 4 do the same thing to the looping variable. Line 2 gets a new value for the looping variable, in this case a new spud to take the place of "the potato" in lines 3 and 4.

The sack is a "collection." It holds the things we want to mess with. We take them from the sack one at a time, until we've processed them all. Let's use this color for collections.

Line 1 is a "loop test." It determines whether we should run the loop again, usually by seeing whether the collection still has things in it that we haven't processed. Let's use this color for the loop test.

Here's the general form of a loop for processing a collection:

  1. While there are more things in the collection:
  2.   Get the next thing from the collection.
  3.   Do something to the thing.

This pattern works for all kinds of loops. A mall Santa:

  1. While there are more kids in the line:
  2.     Get the next kid from the front of the line.
  3.     Ask the kid what presents s/he wants.
  4.     Take a photo with the kid.
  5.     Send the kid away.

Often you need to adjust loops to match the use case:

  1. While there are more kids in the line and the mall is open:
  2.     Get the next kid from the front of the line.
  3.     Ask the kid what presents s/he wants.
  4.     Take a photo with the kid.
  5.     Send the kid away.
  6.     Take a shot of Jack.
  7.     If the bottle is MT:
  8.         Send an elf to get a new bottle.

Suppose you're sending out wedding invitations. You have a list of 72 guests, and some envelopes, invitation cards, and postage stamps. For each guest, you write a name and address on the envelope, put an invitation card in the envelope, put on a stamp, and seal the envelope. Each time, you write a different name and address, but the rest of the steps are the same.

How would you tell a computer how to do this? Maybe:

  1. For each guest on the list:
  2.     Get the name and address from the list.
  3.     Write the name and address on the envelope.
  4.     Put an invitation card in the envelope.
  5.     Put on a stamp.
  6.     Seal the envelope.

There are four different kind of things in the loop:

  • The collection (the list).
  • The looping variable, a single item from the collection (guest's name and address).
  • The loop test (For each guest).
  • Things to do to the looping variable each time through the loop (the yellow stuff).

Getting things from collections

Every program above has a collection:

Take a potato from the sack.

Get the next kid from the front of the line.

For each guest on the list:

It has a looping variable that is one thing in the collection: a potato, the next kid, a guest. We need a way to pull one thing from a collection, then get the next thing, and so on.

How this is done in code depends on how the collection is stored. Let's take a look at the guest list. Here it is:

Array

Remember:

We need a way to pull one thing from a collection, then get the next thing, and so on.

Imagine we had a pointer that we could start at the top of the list:

Array

guestList[pointer] would be Alex, 283 Happy Lane.

Now suppose we did this:

add 1 to pointer

Array

guestList[pointer] would be Alex, 32 Skippy Skip.

Now suppose we did this:

add 1 to pointer

Array

guestList[pointer] would be Pat, 666 Heaven St.

The same code guestList[pointer] - gives something different, depending on the value of pointer.

Geeks call guestList an "array."

JavaScripting arrays

Here's one way to define guestList in JS:

  1. var guestList = [
  2.   { name: "Alex", address: "283 Happy Lane" },
  3.   { name: "Avery", address: "32 Skippy Skip" },
  4.   { name: "Pat", address: "666 Heaven St." },
  5.   { name: "Bobbie", address: "83 Quality St." },
  6.   { name: "Parker", address: "92 Batty Bat" }
  7. ];

Lines 1 and 7 have [, called brackets. JS uses brackets for arrays.

The array has five elements. Each element is an object. Recall that an object is a group of properties. Each one has a key and a value.

If you don't know about JavaScript objects, read this.

guestList[0] refers to the first element in the array. 0 is the index of the element. The second element of the array is guestList[1]. And so on. The fifth and last element in the array is guestList[4] .

This code will show the first three elements in the array:

  1. alert( guestList[0].name );
  2. alert( guestList[0].address );
  3. alert( guestList[1].name );
  4. alert( guestList[1].address );
  5. alert( guestList[2].name );
  6. alert( guestList[2].address );

You can try it.

This code produces the same output:

  1. var pointer = 0;
  2. alert( guestList[pointer].name );
  3. alert( guestList[pointer].address );
  4. pointer ++;
  5. alert( guestList[pointer].name );
  6. alert( guestList[pointer].address );
  7. pointer ++;
  8. alert( guestList[pointer].name );
  9. alert( guestList[pointer].address );

You can try it.

Lines 2 - 3, 5 - 6, and 8 - 9 are the same, but they show different data. Why? Because they use the variable pointer as an index. For lines 2 - 3, pointer is 0. For lines 5 - 6, pointer is 1. For lines 8 - 9, pointer is 2.

guestList[pointer] is an element of the array. Change the value of pointer, and you change which element guestList[pointer] refers to.

Making a loop

Here's the general form for a loop that we saw earlier:

  1. While there are more things in the collection:
  2.   Get the next thing from the collection.
  3.   Do something to the thing.

Let's make a loop that will output mailing labels for all the guests. guestList is the collection. guestList[pointer] is the next thing from the collection. Displaying a label is the something we will do.

There are two JavaScriptisms you need to know about. The first one is the length method. It will tell you how many elements are in an array. So guestList.length returns the number of elements in guestList.: 5.

The second new JavaScriptism is the for statement. We'll just look at one form of it. Try this. Here's the code:

  1. for ( counter=0; counter < 10; counter++ ) {
  2.   $("body").append(counter + " ");
  3. }

Line 2 is the body of the loop. It gets repeated again and again. Notice that it uses the variable counter. This is the looping variable. It changes each time line 2 runs, so line 2 does something a little different each time.

Line 1 is the new thing. It controls the looping variable, counter. The for loop has three parts inside the parentheses (the () ). The first part sets the beginning value of counter:

counter=0

So the first time through the loop, counter will be 0. Line 2 will append 0 and a space to the body.

The third part of the for statement is:

counter++

This is done each time through the loop. ++ means "add one to." So the first time through the loop, counter will be 0. The next time through the loop, counter will be 1. The next time through the loop, counter will be 2. Etc.

The middle part of the for statement is:

counter < 10

This tells JS to keep running the loop while counter is less than 10. The last time through the loop, counter is 9.

Here's another loop:

  1. for ( x=5; x < 9; x++ ) {
  2.   $("body").append(x*x + " ");
  3. }

Predict what it will do, and then try it.

One more. What do you think this will do?

  1. for ( dogs = 2; dogs < 5; dogs++ ) {
  2.   alert("You and " + dogs + " dogs have " + (dogs*4 + 2) + " legs.");
  3. }

Try it.

Mailing labels

OK, the big payoff. Well, not really that big. The payoff, anyway.

Let's write a program to make mailing labels for all of our guests. Try it.

Here's the code:

  1. var guestList = [
  2.     { name: "Alex", address: "283 Happy Lane" },
  3.     { name: "Avery", address: "32 Skippy Skip" },
  4.     { name: "Pat", address: "666 Heaven St." },
  5.     { name: "Bobbie", address: "83 Quality St." },
  6.     { name: "Parker", address: "92 Batty Bat" }
  7. ];
  8. $(document).ready(function() {
  9.     for ( pointer=0; pointer < guestList.length; pointer++ ) {
  10.         labelHtml =
  11.               "<div class='label'>"
  12.             +   "<p>" + guestList[pointer].name + "</p>"
  13.             +   "<p>" + guestList[pointer].address + "</p>"
  14.             + "</div>";
  15.         $("body").append(labelHtml);
  16.     }
  17. });

Lines 1 to 7 create guestList, as before. Line 9 controls the looping variable, pointer. It starts at 0. Each time through the loop, it goes up by one. The first time through the loop, pointer will be 0. The next time through the loop, pointer will be 1. The next time through the loop, pointer will be 2. Etc.

The loop keeps running while:

pointer < guestList.length

Recall that the first element in the array is guestList[0]. The first element has an index of 0. The second element has an index of 1. The third element has an index of 2. Etc.

That means that the last element will have an index that is one less than the length of the array. guestList has five elements, so the last element is guestList[4]. That's why the loop runs while:

pointer < guestList.length

Not while:

pointer <= guestList.length

Even though guestList.length is 5, there is no guestList[5].

This is a common pattern for a loop that processes an array:

  1. for ( pointer=0; pointer < array.length; pointer++ ) {
  2.     Do something with array[pointer];
  3. }

Summary

When you want to do the same thing a bunch o' times, use a loop. The general form of a loop that processes a collection is:

  1. While there are more things in the collection:
  2.   Get the next thing from the collection.
  3.   Do something to the thing.

Loops are particularly good for working with arrays. An array is a collection of data. Each element has an index.