What The For Loop?

Yechiel Kalmenson - Jun 12 '18 - - Dev Community

Learning From A Popular Interview Question

This is another post in the genre of technical interview questions I’ve come across during my job hunt, and how to go about solving them (For more posts see here, here, and here).

Today’s question is a simple one, but the correct answer gets to the basics of a very popular feature in most languages; so popular, we almost never give it any thought.

The question is the following: write a function that prints all the odd numbers up to 20.

Sounds simple, right? Any beginner will tell you that this is a job for a for loop. So let’s write it out:

for(let i=0; i<=20; i++){
  if(i%2===1){
    console.log(i)
  }
} 
Enter fullscreen mode Exit fullscreen mode

In (over)simplified English: we run a loop for 20 iterations, during each iteration of the loop we check to see if the value of a variable i is odd and if it is we print it to the console.

The above function satisfies the requirements. If you run it in your console, you will see it does the job. The question is, is there a better way to do things?

What The For Loop?

Note: for more information about JavaScript for loops see the documentation on W3Schools

Obviously, there is (otherwise there would be no point to this blog post); to understand how, let’s take a closer look at the syntax of the for loop, and more specifically, the first line:

for(let i=0; i<20; i++){
Enter fullscreen mode Exit fullscreen mode

We can see that the for loop takes as an argument three statements separated by ;’s. Let’s take a closer look at them.

The first statement is an expression that is run only one time, before the for loop gets executed. It’s usually used to initialize a counter, but you can put any valid JavaScript expression, or none at all (for example, if you already initialized your counter outside of the for loop). In the example above, the first statement defines a variable i and sets its value to 0.

The second statement is a conditional which gets evaluated before each iteration of the loop. As long as the conditional evaluates to true the loop keeps running. Once conditions change so that the second statement evaluates to false, we break out of the loop. In our example, the conditional is i < 20 so the loop runs as long as the value of i remains below 20.

The third statement is another expression. This expression is run after every iteration of the loop. It’s usually used to increment the counter, but again, you can put any legal JavaScript in there, and it will run (of course, if you aren’t using it to increment a counter you need to make sure you have another way of changing your conditional in the second statement to true, otherwise you will be stuck with a dreaded infinite loop).

Person rolling down Escher's infinite staircase

In our previous example, we are using the third statement to increment the value of i after each iteration, so that after 20 iterations i is equal to 20, i < 20 evaluates to true, and we break out of the loop.

We Can Do Better

Now let’s take a look at our function and see how we can optimize it.

As a refresher here is the function:

for(let i=0; i<=20; i++){
  if(i%2===1){
    console.log(i)
  }
}
Enter fullscreen mode Exit fullscreen mode

So we set the value of i to zero and start the loop. At each iteration of the loop we check the current value of i, if it’s odd, we log it to the console, and then we increment i by 1 and rerun the loop until i hits 20 at which point we break the loop.

How can we optimize this?

The key is in the third statement. As mentioned earlier, nothing is forcing us to increment our counter by 1 in the third statement; we can do whatever we want. Combining that knowledge with the fact that 1 is an odd number, and that adding 2 to an odd number gives us an odd number as well and the result is a loop that only has to run half of the iterations our previous attempt used.

Try putting the following in your console and see how it runs the same:

for(let i=1; i<=20; i +=2 ){
  console.log(i)
}
Enter fullscreen mode Exit fullscreen mode

The differences between this function and the previous one is that here we set the initial value of i to 1 and instead of incrementing i by one for each iteration we increment it by two (we also got rid of the if statement because we know that now i is always odd, so we just log the value of i each time without checking).

So we see how sometimes knowing how things work under the hood can help us when we want to tweak them beyond the way they are usually used.

I hope this post inspired you to sometimes delve a little deeper, even into concepts that “everyone knows”.

Happy coding!


This article has been cross-posted from my blog Rabbi On Rails.
You can read more about my coding journey there, or by following me on Twitter @yechielk

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .