Nested loop returning limit

Viewed 65

I am working on a quiz for an online course.

For this quiz, you're going to create a function called buildTriangle() that will accept an input (the triangle at its widest width) and will return the string representation of a triangle. See the example output below.

buildTriangle(10);

returns
* 
* * 
* * * 
* * * * 
* * * * * 
* * * * * * 
* * * * * * * 
* * * * * * * * 
* * * * * * * * * 
* * * * * * * * * * 

I solved it using this function:

function buildTriangle(length) {
    var line = "";
    var triangle ="";
    for (h = 1; h <= length; h++) {
        makeLine(length);
        function makeLine(length) {line += "* ";}
        triangle += line + "\n";
    }
    return triangle
}

buildTriangle(10));

Which successfully returns:

* 
* * 
* * * 
* * * * 
* * * * * 
* * * * * * 
* * * * * * * 
* * * * * * * * 
* * * * * * * * * 
* * * * * * * * * *

However, before getting to this solution, I tried this:

function buildTriangle(length) {
    var line = "";
    var triangle ="";
    for (h = 1; h <= length; h++) {
        makeLine(length);
        function makeLine(length) {
            for (i = 1; i <= length; i++) {
                line += "* ";
            }
        }
        triangle += line + "\n" 
    }
    return triangle
}

console.log(buildTriangle(10));

Which returned this:

* * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

Why does this nested makeLine function not go through the loop normally (i.e. starting at 1), but instead produce 10 every time? Is there a way to force the loop to run normally (1, 2, 3, 4, 5...)? Why does this nesting not work?

4 Answers

Because you have a loop in makeLine which is looping from 1 through length (inclusive), and you're using += when adding to line. So the line is going to get "* " added to it length times, each time you call makeLine.


Side note: There's no reason to have the makeLine function at all. But if you're going to have it, don't declare it within the for. That used to be invalid (though browser JavaScript engines tolerated it in some cases). It's no longer invalid, but there's no good reason for it here.

Side note 2: Your code is falling prey to what I call The Horror of Implicit Globals. You need to declare your h (and i) variables.

Issue 1

The first issue with your second function is that you are passing length into makeLine instead of h:

function buildTriangle(length) {
    var line = "";
    var triangle ="";
    for (h = 1; h <= length; h++) {
        makeLine(h);
        function makeLine(length) {
            for (i = 1; i <= length; i++) {
                line += "* ";
            }
        }
        triangle += line + "\n" 
    }
    return triangle
}

console.log(buildTriangle(10));

Issue 2

Next, you will notice that the triangle is adding h extra than need be. That's because you have line set to concatenate and not clear after each run:

function buildTriangle(length) {
    var line = "";
    var triangle ="";
    for (h = 1; h <= length; h++) {
        makeLine(h);
        function makeLine(length) {
            line = "";
            for (i = 1; i <= length; i++) {
                line += "* ";
            }
        }
        triangle += line + "\n" 
    }
    return triangle
}

console.log(buildTriangle(10));

Presto! Fixed the issue and it should now be running as expected!

The inner and outer loop conditions are checking against length which is 10, so you get 10 *s every time the inner loop runs. To get the intended result you can compare i to h instead of length.

Also, it is a bad idea to redeclare the function inside of each iteration of the loop.

Your makeline inner function should not take length as parameter since length is the widest with of the triangle. Instead, makeline has to use the exact width to print at that instance. And in this case, your h. Otherwise, your makeline will print length*length lines at the end.

Related