Code for recursion finally working - Grabbed recursion, back to studying

I didn’t want to look at the solutions but it seems I’m stuck here. Pardon my stupidity.

function rangeOfNumbers(startNum, endNum) {
  if (startNum > endNum) {
  return [];
 } else {
   const arr = [startNum <= endNum];
   arr.push(startNum + 1);
   return arr;
 }
};

Returns:

// running tests
rangeOfNumbers(1, 5) should return [1, 2, 3, 4, 5]
rangeOfNumbers(6, 9) should return [6, 7, 8, 9]
rangeOfNumbers(4, 4) should return [4]
// tests completed

Navigated to Learn Basic JavaScript: Use Recursion to Create a Range of Numbers | freeCodeCamp.org

Can you explain this line please?

@ArielLeslie It’s meant to be that the startNum is less than or equal to the endNum. And that defines an array.

This is a boolean test.

This is an array with a boolean value inside.

@JeremyLT Thank you. You’re right. What I have to write here is an arythmethic expression instead. Am I right here?

Instead of starting with code and trying to force it into the right shape, I suggest figuring out the logic of your solution first.

Right now you are not making any recursive calls. Can you work out (in words, not code) what process a call to rangeOfNumbers needs to go through?

2 Likes

@ArielLeslie The process starts with a number. You have to add one to that number until it reaches another number that has to be larger than or equal to the first. Then put all the numbers obtained during the process into an array in ascending order.

What number? How is it determined? What other number? How is it determined? What do you mean by “add one to that number”? What do you mean by “all the numbers”? You only mentioned two numbers. Where did the other numbers come from? Where are they stored? What process do you use to turn these numbers into an array? How do you get them in ascending order?

Where is the recursion?

1 Like

What does that mean? How will the output look after you do this?

You have talked about two numbers. What are these numbers?

How? What about this part is recursive?


Recursion is all about making your problem smaller and smaller until you have a simple base case. What is the most basic version of making a range? How can you use the basic version to solve a more complex version?

1 Like

@JeremyLT I think you have explained something I hadn’t quite grasped yet with your definition of recursion. I’ll think about both your sets of questions and try to answer them without code. Then I’ll see about the code. Thank you both. Sometimes I think I’m losing my time when I fail to understand the basic of things. Maybe this isn’t for me. But I’m stubborn, I don’t know why yet.

@camperextraordinaire Thank you very much, really! Many say how difficult JavaScript is, and recursion is, but sometimes I feel plain stupid. So your kind words make me feel like I can do it. Maybe I’m slower, I won’t get it tomorrow, I won’t get it next month…but I’ll keep on trying until I can. Thank you so much you three have helped me a lot. I don’t think I lost my time coming here to ask. So I’ll try.

1 Like

@JeremyLT Let’s see whether I made some progress.
It’s easier for me to speak in code and to think in code. Maybe that’s my mistake.
How I responded to the question

is making an array that contains the numbers that are equal, in sucession, to one number minus other number plus one.
That in the beginning equals to

const arr = [endNum - startNum + 1];

I thought about this because of your question of what is the most basic version of making a range.
But I’m having problems to get to the part where the resulting numbers are added one after the other in sucession. To add a number at the end of an array I used push but I can’t figure out what goes inside the parentheses. It has to be the first number plus one once and again, so I wrote

startNum++

I hope at least this is recursion. But needless to say, it doesn’t pass.

What’s your updated code? Are you calling the function inside of the function? That’s how you reduce the problem down to the base case.

You can always start with the basic structure of the recursive function. All recursive functions will have this structure:

func recur( . . . ) {
  if (is_it_an_endcase?) {
      //perform the end case
  } else {
     //perform the recursive case
     // call recur() with an argument different (smaller) than the parameter received here

The key point is that you will always have a call to itself inside the function body. Your code does not have a recursive call in the function body.
Suppose you want a recursive function to print a countdown.

func countdown(n) {
  for (let i = n; i >=0; i--) {
    console.log(i);
  }
}

How would you do this recursively? Let’s start thinking with the basic structure. What would be the end case in this problem? When the parameter n is zero, we’re done. We’ll do the final print. We have something like

func rec_countdown(n)  {
  if (n == 0) {
    console.log(0);
  } else {
     //recursive case
  }
}

To think the recursive case, you can imagine yourself as a recursive function and there are multiple clones of you. You take one finite action and delegate to your clone to finish up the remaining task. You can think like this

func rec_countdown(n)  {
  if (n == 0) {
    console.log(0);
  } else {
    console.log(n);
     //recursive case: since you printed out n, you ask your clone to take care of
    //count down from n-1
    rec_countdown(n-1);
  }
}

Now, the function rec_countdown() does not return any value (i.e., there’s no explicit ‘return’ statement). It gets slightly harder when you have to return a value in a recursive function, but the basic structure remains the same.
Suppose you want to build a list containing n numbers of a string “hello”. You can think recursively like this: You get N as a parameter. You ask your clone to create a list of N-1 ‘hello’. You then add one more ‘hello’ and pass the result back to your caller. If the passed parameter is 0 then you return an an empty list.

func rec_create(n) {
  if (n == 0) { //or n <= 0 to handle negatives
    return [];
  } else {
    let arr = rec_create(n-1); //your clone returns a list of n-1 'hello's
    arr.push("hello");    //you add one more 'hello' to the list; now there's n 'hello's
    return arr;   //then you return the result to your caller
  }
}

For the rangeOfNumbers function, you can build the list either backward or forward. If you have low and high as parameters, your clone can build a list of [low+1, …, high] or [low, … , high-1].
As mentioned, recursion is hard. I hope this helps.

2 Likes

First of all, I’m sorry for responding so late. I have a complicated life and sadly I can’t devote to study the time I would like to. Maybe that’s one of the reasons why I fail so much. Maybe not.
@JeremyLT Here’s my updated code:

function rangeOfNumbers(startNum, endNum) {
  if (startNum > endNum) {
  return [];
 } else {
   const arr = [endNum - startNum + 1];
   arr.push(startNum++);
   return arr;
 }
};

I thought I called the function by the return arr; line. I must be wrong because it doesn’t work.

You function is called rangeOfNumbers. You need to call rangeOfNumbers inside of rangeOfNumbers for the function to be recursive.

1 Like

@twotani I’ve studied your words and I must say I don’t quite understand everything you said. I’ll try to reread it until I get it because it obviously makes sense. Thank you for taking the time to explain all of this to me. You’re too kind.

@JeremyLT That’s crystal clear.

@JeremyLT I’m calling the function now through console.log
I think I finally got recursion. But what’s killing me is the arythmethic inside the array for it to get all the numbers in sucession one by one between startNum and endNum.
Give me some days and I will do it hehe.

@JeremyLT I used unshift. That was a step ahead.