最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to replace while with a recursive function? - Stack Overflow

programmeradmin9浏览0评论

I'm using while in this fashion:

while (value < -180 || value > 180) {
  if (value < -180) {
    value += 360
  }
  if (value > 180) {
    value -= 360
  }
}

I would like, though, to use a recursive function instead of while. I searched on Google but couldn't find anything. So I thought maybe I could get the answer here.

I'm using while in this fashion:

while (value < -180 || value > 180) {
  if (value < -180) {
    value += 360
  }
  if (value > 180) {
    value -= 360
  }
}

I would like, though, to use a recursive function instead of while. I searched on Google but couldn't find anything. So I thought maybe I could get the answer here.

Share Improve this question asked Aug 4, 2017 at 1:50 alexalex 7,61115 gold badges53 silver badges80 bronze badges 10
  • 2 Why use recursion? Unless the problem specifically benefits from a recursive solution, recursion can hinder your program. – Carcigenicate Commented Aug 4, 2017 at 1:50
  • 1 @Carcigenicate I want to avoid using while for personal reasons. – alex Commented Aug 4, 2017 at 1:51
  • 1 I would encourage you to consider those personal reasons carefully. Every tool has its place. – Carcigenicate Commented Aug 4, 2017 at 1:52
  • How could if (value < -180) be true if while (value < -180 || value > 180) is true? What is input and expected result? – guest271314 Commented Aug 4, 2017 at 1:56
  • 1 Alex, as aptly pointed out by @Carcigenicate , recursion can hinder your program. In general, recursion that isn't optimized away by the interpreter/piler (isn't converted into a while loop) is usually more expensive, slower and includes an inherent stack overflow risk. It's good that you're learning about recursion, but you should also learn about it's risks and limitations. – Myst Commented Aug 4, 2017 at 2:16
 |  Show 5 more ments

2 Answers 2

Reset to default 5

The "general formula" for converting an explicit loop to a recursive solution is:

  • Figure out what the "accumulators" of the loop are. Often, the loop will be manipulating one or two values, and those values are the "result" of the loop.

  • Make the accumulators the parameters of a function.

It's difficult to generalize how any old loop can be replaced with recursion, but this can be used as a general guideline:

For a loop with the form:

var a, b, c = ...;

while (condition) {
   // Change a, b, c...
}

// Use a, b, c

You can convert that to:

function recursive(a, b, c...) {
   // When the condition does *not* hold, end the recursion.
   // Note that condition is negated relative to the while-loop.
   if (!condition) {
      // Base case.
      return [a, b, c...];

   } else {
      // Change a, b, c...
      //  and recurse with the new values
      return recursive(a', b', c'...);
   }
}

For your example, this would look something like:

function recur(value) {
  if (value > -180 || value < 180) {
    return value; // Base case

  } else if (value < -180) {
    return recur(value + 360);

  } else {
    return recur(value - 360);
  }
}

In cases where you expect to loop again, recurse, but remember that you need to return the result of the recursion. For cases where you want to end the loop, return the accumulator. Note that every branch of execution must end in a return. As soon as you discard the result of a recurse (by not returning it), the data is lost.

Note though:

  • As I mentioned in the ments, recursion isn't a hammer that should be thrown at just any old problem; especially when the language isn't optimized for it. It may be fine for small problems, but down the road, you may find it will suddenly start causing StackOverflows out of nowhere when the problem bees bigger.

  • Recursion can bee difficult and confusing when dealing with mutable data. If your accumulators are mutable (a list, map, or any other non-primitive), you must be very careful with how you set everything up. The same data will be able to be accessed and changed from every branch of the recursion. If you aren't careful, you'll have your accumulators being changed out from under you in very hard-to-debug ways. If you want to go the recursive/functional path, I'd encourage you to look into a library like Immutable.js, or a language like Clojurescript that deals almost exclusively with immutable structures. Clojurescript piles into JavaScript.

Try this:

var recur_num = recursion(500)
console.log(recur_num)

var while_num = viaLoop(500)
console.log(while_num)

function recursion(value) {
  
  if (value < -180) {
    return recursion(value + 360);
 } 
  
  if(value > 180){
    return recursion(value - 360);
  }
  
   if (value > -180 || value < 180) {
    return value; 
  }
}


function viaLoop(value){

while (value < -180 || value > 180) {

 if (value < -180) {
    value += 360
  }
   
  if (value > 180) {
    value -= 360
  }
}

return value;
}

You can pare both the recursion version value and the while loop version value

发布评论

评论列表(0)

  1. 暂无评论