Luis Gonzalez
Luis Gonzalez

Reputation: 45

How can I recurse in JS to repeat a string n times?

I am trying to make the code below repeat string s n number of times, however, it will always repeat n - 1 times, because I need to pass a decrement to exit the recursion or I will exceed the max call stack.

function repeatStr (n, s) {
  while(n > 1) {
   result = repeatStr(-n, s)
    return s = s.concat(s)
  }
}
repeatStr(3, "Hi")

What can I change to make it recurse correctly?

Upvotes: 0

Views: 2027

Answers (3)

Mulan
Mulan

Reputation: 135197

Adding a decomposed approach to the other nice answers in this thread -

const concat = a => b =>
  a.concat(b)

const repeat = n => f =>
  x => n && repeat(n - 1)(f)(f(x)) || x
  
const hello =
  repeat(3)(concat("Hi"))
  
console.log(hello("Alice"))
console.log(hello(""))

HiHiHiAlice
HiHiHi

Upvotes: 1

Stephen Quan
Stephen Quan

Reputation: 25906

Because you're new to programming and JavaScript, let's work up to the solution. Start with a simple case, e.g. repeatStr(3, "Hi"). One simple answer may be:

function repeatStr(n, s) {
    return "HiHiHi";
}

Here, we assume what the inputs are always 3 and "Hi". We don't have a while loop, and we don't have recursion. We have the correct answer for those specific inputs but no other inputs are supported.

Let's make the answer a little bit harder:

function repeatStr(n, s) {
    return "Hi" + "Hi" + "Hi";
}

Here, again, we are assuming the inputs are 3 and "Hi". We still don't have a while loop nor do we have recursion.

Okay, let's start using one of your inputs:

function repeatStr(n, s) {
    return s + s + s;
}

Here, we are finally using the string that's passed in as s. We can handle inputs other than "Hi" to generate a correct answer. But, we're still assuming the number input is 3.

Finally, let's have a look at n:

function repeatStr(n, s) {
    let result = "";
    while (n > 0) {
        n = n - 1;
        result = result + s;
    }
    return result;
}

Okay, here we take both inputs n and s into consideration and we solve the problem by appending s exactly the number n times needed. This is a while loop solution, not a recursion solution. Our while loop has the action result = result + s; repeated exactly n times where we use n as a countdown and stop when we reach 0.

Now, we have all that background, let's look at one version of the recursion solution.

 function repeatStr(n, s) {
     if (n <= 0) {
         return "";
     }
     return s + repeat(n - 1, s);
 }

Even in recursion form we retain the countdown feature. This time the countdown is used to drive the recursion instead of a while loop. We still counting down to 0 where we have an if-return guard condition that's needed to terminate the recursion. i.e. when n <= 0, we exit with the simple empty string "". Then for the more complex case, it is solving any nth version by expressing in terms of the (n-1) th version. Another way of looking at it is this:

 repeatStr(3, "Hi") === "Hi" + repeatStr(2, "Hi")
                    === "Hi" + "Hi" + repeatStr(1, "Hi")
                    === "Hi" + "Hi" + "Hi" + repeatStr(0, "Hi")
                    === "Hi" + "Hi" + "Hi" + ""

If you want to get a little clever, JavaScript has a conditional which can be used in place of your if statement:

 function repeatStr(n, s) {
     return (n <= 0) ? "" : s + repeat(n - 1, s);
 }

Hope that makes sense.

Upvotes: 2

Chris Herring
Chris Herring

Reputation: 3665

Recursion involves making a function call itself and AVOIDS using a loop. You have a loop in the recursive function which is a big red flag.

Do something like this: If n is 1 return s else return s concatenated to the result of the function with n - 1.

function repeatStr (n, s) {
   if (n == 1) 
       return s;
   else
       return s.concat(repeatStr(n - 1, s))
}
repeatStr(3, "Hi")

Upvotes: 3

Related Questions