Counting up and down in recursive manner in JS

Tags: , , ,



I am currenty working on functional programming techniques. There are topics about this issue [ especially there is one about java ] but not about JS.

I want to create a recursive function that can first, count up until the limit I decide, from the number I indicate and then start counting down when the limit is reached. I can already do this with a for loop but it feels like hard-coded since i am supplying the numbers in the loop.

Basically something like this:

counter(0,10);
// 0, 1, 2, 3 ... 10, 9, 8... 0

Here’s what I thought of:

counter = (number, limit) => {
limit !=== 0

if ( number = limit ) {
  counter(number -1, limit -1)
  console.log(number)
} else if ( number < limit ) {
  counter(number + 1, limit + 1)
  }
}

Idea behind this is, if the number is lower than the limit count up, if they are equal, decrement each argument by 1 to continue satisfying the first if condition.

When I run this command on v8, it gives a rangeError “maximum stack size reached”.

Also, this should not be an infinite loop.

For loop version:

for (let i = 0; i < 11; i++ ) { console.log(i) }
for (let i = 9; i < 11 && i > -1; i--) { console.log(i) }

Answer

You don’t need to loop back down or decrement the value, as when you reach your base-case (the thing that stops the recursion), then you’ll jump back up the calling function, which holds the previous value:

counter(0, 10) // logs: 0
    |           ^
    |           | (returns back to)
    |---> counter(1, 10) // logs: 1
              |             ^
              |             | (returns back to)
              |---> counter(2, 10) // logs: 2 <---
                        |                         | (returns back to)
                        |                         |
                        ........   ---> counter(10, 10) // logs: 10 - base case

Each call of counter() will call counter again (shown in the above diagram with the child counter calls), these then print their current value. When you reach the base case, you print the current value, and return, which causes you to pass control back to the calling function. By this I mean that when you call a function, the function will run. When the function finishes, the code picks up back from where the function was originally called:

function bar() {
  console.log("bar");
}

console.log("foo"):
bar(); // call the function makes the code execution jump up into `bar` function. When that completes, our code execution jumps back to the next line, which logs "baz"
console.log("baz");

in our counter() example, the place which called the child counter() functions are its parent counter function, which we jump (pass control back to) when the child function finishes executing (returns). Once control has been passed back. to the calling function (ie: the parent function in the diagram above) you can then log the value of again as that contains the previous value of value:

function counter(value, limit) {
  if(value === limit) {
    console.log(value);
  } else {
    console.log(value); // on the way down / going deeper (increment)
    counter(value+1, limit);
    console.log(value); // on the way up / coming up from the depths (decrement)
  }
}

counter(0,10);
// 0, 1, 2, 3 ... 10, 9, 8... 0


Source: stackoverflow