Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 1072 of the free egghead.io lessons, plus get JavaScript content delivered directly to your inbox!



Existing egghead members will not see this. Sign in.

Intro to Recursion - The Solution

4:39 JavaScript lesson by

In this lesson we manage to remove all of the nested loops that helped us towards a partial solution in the first lesson. We create a function getTasks, that can, only under certain conditions, call itself. This is the basis of recursion and often leads to cleaner, shorter code that can handle more dynamic input.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

In this lesson we manage to remove all of the nested loops that helped us towards a partial solution in the first lesson. We create a function getTasks, that can, only under certain conditions, call itself. This is the basis of recursion and often leads to cleaner, shorter code that can handle more dynamic input.

Avatar
Jaime

The attached JSBin is not working. It is saying a JS BIN Pro Account is required.

In reply to egghead.io
Avatar
beckinfonet

Shane Osborne is a great instructor, but why did he have to chose a horrible and confusing example to explain recursion? For some of the people like me who just started to learn recursion, he could have chosen some words that make more sense. I watched it 5 times, I keep thinking why on earth did he choose these words as an example. But thanks anyways for the explanation.

In reply to egghead.io

Recursion is a great way to avoid nested loops like this. This example from the previous lesson shows how we can create a flat array given some input such as Build and a configuration object like this. Because Build exists as a key on the config object, we would then add each of these items to a tasks array. Unless the item we're adding is also a key here, in which case we will instead add those items that are associated to it, the idea being that we will end up with this flat array that only contains task names.

Let's recreate the same result, but instead of using nested loops like this, we'll use a recursive function. We'll call it Get Tasks, which will take our input and we can loop over that as we did before.

On the first run-through, Task is now going to be equal to Build, in which case we can check if it exists on the configuration object. If it does we now need to look at this array. But whereas previously we would have another nested loop inside here. If you look at Get Tasks it actually just takes in an array. This is the recursive part of this function.

We can actually call the same function again, but this time passing in a different array. When this runs, and this is equal to Build, we see it here. We get access to the array here and we pass it back in to get tasks.

Now an input runs. The first item is going to be JS. This check will occur again. It will see it here and then it will call Get Tasks again. This time, it's being called with this array. For the first iteration Tasks will now be equal to lint. Because lint does not exist as a key on the config object, this block of code never runs.

We can say else tasks.push task. This is an important part of a recursive algorithm, is that it must end somewhere. In our case we are going to keep calling this Get Tasks function with a different array each time until the items in that array no longer match a key on the left here, at which point we simply add it to the array and then the whole thing repeats.

This means we end up adding lint and uglify from the JS command. Then it runs again with CSS and the whole process repeats. Task ends up being equal to Sass and then Cssmin, which don't match here and get added to the array. Finally, when both of those paths have been exhausted this is called with VersionRev. VersionRev does not exist as a key here, so it also ends up at this point.

Now if we call this function to begin the process, we can pass along our input, run it, and you can see we get exactly the result we wanted with just this simple little function. Not only is this less code and easier to maintain, it can also do something that the previous example couldn't. If we do the same thing, add another command code Dist that calls Build and then Deploy, change our input to instead be Dist, then if we run it you can see we get the correct result.

This is one of the main benefits of using recursion. It doesn't matter how deep the nesting goes. The function can just keep calling itself over and over again with different arrays until eventually, this conditional evaluates to false. Then we end up inside of this Else block instead, in which case we just add the current item to the Tasks array and that part of the recursive loop is over.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?