Letters to an Aspiring Programmer - On Loops
A good friend is learning how to program. I'm naturally psyched. He's tracking the topic and amount of time he's investing into learning how to code with Codecademy on Didsum, which makes it easy for me to follow along with progress. I thought it might be fun, and potentially helpful, to write some quick commentary around the topics he's learning and post them here. Today's notes are about Looping.
Patrick,
Nice work getting through the section on looping today! Being "a bit shaky with them" is nothing to worry about. The details about loops are hard to remember, especially from tutorials that force feed you details too early.
Covering the full power of loops in a single tutorial is kind of like trying to teach someone new to baseball all of the grips and releases a pitcher could use. Until you need to throw a curve ball, knowing exactly where to hold your fingers around the stitching and how to release it isn't a big deal.
Once you're writing a program to do something you need it to do, you'll probably hit points where you think "I need to do something a bunch of times" or "I have a bunch of data, I need to do something with every piece of it." When you find yourself thinking that, loops are a powerful tool at your disposal1.
Once you have a need, and can jot down a basic outline of your strategy for solving it (in English), you can search Google for "types of loops" to decide which kind of loop to use or its specific syntax. Test and tweak until you get it right.
Common Purposes of Loops
After you've used loops for a while, some patterns will start to emerge in how you use them to help you with a particular kinds of tasks. These tasks are not worth trying to commit to memory, but they're common enough that being aware of them should be useful. All of these examples will use for loops over arrays.
Do something for each element
var numbers = [1, 2, 3, 4, 5];
// For each number in the `numbers` array:
// log it to console
for(var i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
}
This was the opening demo of your Codecademy tutorial. It loops through each number in the numbers array and takes an action with it. In this example, the action is to print it to console. The action could have been alert(numbers[i]);
to get it to show an alert dialog for each number. There will be times when you just need to take an action with every element in an array and this simple pattern will have you covered.
"Change" elements of an array
var numbers = [1, 2, 3, 4, 5];
var numbers_doubled = [];
// For each number in numbers:
// double it and add it to the numbers_doubled array
for(var i = 0; i < numbers.length; i++) {
numbers_doubled.push(numbers[i] * 2);
}
In this demo, our goal is to double an array of numbers. The doubling isn't important, what is important is that after we're done we have a new array whose elements are "mapped" from the elements of the original array. In this case, that mapping is to double the element. Maybe your array is made up of investments and you want apply interest on each of them.
Note: We could have changed the elements of original numbers
array in place, without using the separate numbers_doubled
array, and that would have been fine. One upside of creating a new array is that we still have a way to access our original data later in the program. Another upside is that this program will be easier to debug.
Filter elements of an array
var numbers = [1, 2, 3, 4, 5];
var odds = [];
// For each number in numbers:
// if it is odd, add it to the odds array
for(var i = 0; i < numbers.length; i++) {
if(numbers[i] % 2 == 1) {
odds.push(numbers[i]);
}
}
In this demo, our goal is to pick out all of the odd numbers
in the numbers array and place them in the odds
array.
Note: If you haven't seen the %
modulo syntax before, it's basically "integer division remainder", i.e. if you divide 3/2 you get a remainder of 1.
When you have a dataset, but only want to focus on a particular chunk of it, you can filter out exactly the data you want using a loop to populate a new, filtered dataset. Creating a new variable to copy the elements you do want into a new array is usually simpler than removing the items you don't want.
Summarize elements of an array
var numbers = [1, 2, 3, 4, 5];
var sum = 0;
// For each number in numbers:
// add it to the sum variable
for(var i = 0; i < numbers.length; i++) {
sum = sum + numbers[i];
}
In this example, we're adding up all the numbers. We could have done other things, too, like averaged the numbers. The important takeaway is that we initialized a new variable, sum, to hold the results of our computation. Once we've looped through the array, and reduced it down to a single value, we now have their sum.
For a lot of common mathematical summaries (like sum, product, average, stddev, etc.) there will be libraries you can use so you do not have to write these computations by hand. When you find yourself wanting to summarize in your own special way, this is a useful pattern to come back to.
Conclusion
Don't worry about the details of loops until you find yourself needing to do something repeatedly. The important thing to know is that they exist. If you can frame your problem as one or more of the different common types of loops I demoed above: taking repeated actions, modifying a bunch of values, filtering out values, or summarizing values, then you can use those patterns as building blocks.
Once you're more comfortable with functions in JavaScript, it'll be fun to revisit these looping concepts with the full power of functions at your command. Once you've got functions down we could write some that allow you to avoid the hassle of writing loops altogether. Let's save that glory for a rainy day.
Best,
Kris