I have a question about JS increment(++). I know many people here asked about ++ and +1 difference in JS but none of them mentioned it in recursive call sentence.
QUESTION:
I want to call function exec inside exec function recursively but the flowing script is not working well.
var exec = function(index){
if(index<7){
exec(index++);
}
}
exec(0);
output: Uncaught RangeError: Maximum call stack size exceeded
So I changed my script to the below and it worked well.
var exec = function(index){
if(index<7){
exec(index+=1);
}
}
exec(0);
Why it acts like differenctly in this example? Is my recursive call wrong?
index++ is post-increment. That means it increments the variable, but the value of the expression is the old value. So:
exec(index++);
is equivalent to:
var oldindex = index;
index += 1;
exec(oldindex);
So the recursive call uses the old value, which means you keep calling recursively with the same value, and never hit the limit that stops recursing.
You need to use pre-increment, which increments the variable and returns the new value:
exec(++index);
Actually, there's no reason to increment the variable at all, since you never uses it again in that function. Just do:
exec(index + 1);
The issue with index++ is that it is a post-increment, so it only increments the value of index after it's already been passed back into exec. Using the pre-increment (++index) should work, since it will then increment it before passing it into the recursive call.
var exec = function(index){
console.log(index)
if(index<7){
exec(++index);
}
}
exec(0);
Related
In the following code, I tried to keep timeout but it doesn't work. I am sending array and expecting array index with 3 sec delay.
function displayIndex(arr){ // array as input
for(var i=0;i<arr.length; i++){
SetTimeout(function(){
console.log(i); // always returns 4
},3000);
}
}
displayIndex([10,20,30,40])
update:
var arr = [10,20,30,40];
function displayIndex(arr){ // array as input
for(var i=0;i<arr.length; i++){
setTimeout(function () {
var currentI = i; //Store the current value of `i` in this closure
console.log(currentI);
}, 3000);
}
}
displayIndex(arr); // still prints all 4.
Also, tried
arr.forEach(function(curVal, index){
setTimeout(function(){
console.log(index);
},3000);
}); // prints 0 1 2 3 but I do not see 3 secs gap between each display, rather one 3 sec delay before everything got displayed.
Use this:
function displayIndex(arr){ // array as input
var i=0;
var current;
run=setInterval(function(){ // set function inside a variable to stop it later
if (i<arr.length) {
current=arr[i]; // Asign i as vector of arr and put in a variable 'current'
console.log(current);
i=i+1; // i increasing
} else {
clearInterval(run); // This function stops the setInterval when i>=arr.lentgh
}
},3000);
}
displayIndex([10,20,30,40]);
1st: If you use setTimeout or setInterval function inside a for that's a problem 'couse all this are loops ways (the first two are loops with time intervals). Aaand setTimeout just run code inside once.
Note: setInterval need a function to stop it clearInterval, so that's why i put an if inside.
2nd: You are not setting currentI or i like a vector of arr operator. When you run an array the format is: arr[currentI], for example.
Doubts?
SetTimeout should be setTimeout. It's case-sensitive.
You're setting 4 timeouts all at once. Since you're incrementing the value of i every loop, it's going to be 4 at the end of the loop.
I'm not really sure what you're trying to do, but perhaps you wanted this?
setTimeout(function () {
var currentI = i; //Store the current value of `i` in this closure
console.log(currentI);
}, 3000);
The reason why it's behaving unexpectedly:
Case 1: In the first snippet, setTimeout() is adding the functions to the Event Queue to be executed after main thread has no more code left to execute. The i variable was passed as reference and, so the last modified value gets printed on each call since, it was passed by reference.
Case 2: In this case, since you are passing 4 explicit references, the values are different but, the execution order will same ( I.e., synchronous and instantaneous).
Reason: setTimeout() function always pushes the function passed to the queue to be executed with the delay acting as a minimum guarantee that it will run with the delayed interval. However, if there is code in the queue before the function or, any other code in the main thread, the delay will be longer.
Workaround: If you do not to implement blocking behaviour in code, I would suggest using an analogue of process.hrtime() for browser ( there should be a timing method on the window object and, write a while loop that explicitly loops until a second has elapsed.
Suggestion: I am somewhat confused as to why you need such blocking in code?
I have an assignment to count repeated strings base on a Heap's Algorithm Permutation.The first thing I want to do is output the swapped strings, I found this code from jake's answer Can someone please help me understand recursion within this code in a loop? The output of this function are swapped strings.
function permAlone(string) {
var arr = string.split(''), // Turns the input string into a letter array.
permutations = []; // results
function swap(a, b) {
debugger; // This function will simply swap positions a and b inside the input array.
var tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
function gen(n) {
debugger;
if (n === 1) {
var x =arr.join('');
permutations.push(x);
} else {
for (var i = 0; i != n; i++) { // how does this loop executes within the call stack?
gen(n - 1);
debugger;
swap(n % 2 ? 0 : i, n - 1); // i don't understand this part. i understand the swap function, but I don't get how indexes are swapped here
}
}
}
gen(arr.length);
return permutations;
}
permAlone('xyz'); // output -> ["xyz","yxz","zxy","xzy","yzx","zyx"]
I have been experimenting it on debugger but still can't get what's happening.
I'm not sure what you mean by
understand recursion within this code in a loop
If you mean you want to see the algorithm in a loop form rather than a recursion version you can see them one by side in pseudocode in the wikipedia page here.
For your questions within the code:
how does this loop executes within the call stack?
You are right to refer to the call stack, and this is a general question regarding recursion. If you don't understand how recursion works with the stack you can refer to this really nice and simple video that demonstrates recursive calls using factorial calculation in java (start around min 4:00).
The line you look at is no different than any other line in the recursive function. We start by defining i and assigning the value 0 to it. We continue to check if it satisfies the condition of the for loop. If it does we step into the loop and execute the first line inside the loop which is the recursive call. Inside the recursive call we have a new stack frame which has no knowledge of the i variable we defined before executing the recursive call, because it is a local variable. So when we get to the loop in the new call we define a new variable i, assigning it 0 at first and incrementing it as the loop repeats in this stack frame/call instance. When this call finishes we delete the stack frame and resume to the previous stack frame (the one we started with) where i=0 still, and we continue to the next line.
All the calls have access to the arr and permutations variables since the function is defined in the same scope as the variables (inside the function permAlone) so within each call - no matter what the stack frame we are in, the changes made to those are made to the same instances. That's why every push done to permutations adds to the existing results and will be there when the function returns the variable at the end.
i don't understand this part. i understand the swap function, but I don't get how indexes are swapped here
Indexes are not swapped here. It is merely a call for the swap function with the correct indices.
swap(n % 2 ? 0 : i, n - 1);
is just
swap(a, b);
with
a = n% 2 ? 0 : i;
b = n - 1;
If the a part is what confuses you, then this is a use of the ternary operator for conditional value. That is, it's symbols used to form an expression that is evaluated differently according to the circumstances. The use is by
<<i>boolean epression</i>> ? <<i>value-if-true</i>> : <<i>value-if-false</i>>
to evaluate the above, first <boolean expression> is evaluated. If it's value it true then the whole expression is evaluated as <value-if-true>. Otherwise, the whole expression is evaluated as <value-if-false>.
In the code itself, for a, n % 2 is the boolean expression - js divides n by 2 and takes the remainder. The remainder is either 1 or 0. js implicitly converts those to true and false respectively. So if n is odd we get
a = 0
and if it's even we get
a = i
as the algorithm requires.
I have a function that calls itself and I don't see any potential infinite-loops and I am only running the loop if the counter is less than the length of an array.
Does anyone have any idea why the call stack size is throwing an error?
function train(i, data, n, nTwo, func){
if(i===data.length && nTwo!==undefined) done();
else if(netTwo===undefined) func();
else (new Trainer(n)).workerTrain([data[i]], train(i++, trainingSet, l, y));
}
train(0, trainingSet, l, y);
I can't run this inside a for-loop as I can initiate a worker until the previous one is done. Or at least when I tried to, I got an error.
So I'm running the next worker in the previous worker's callback function.
You are using the post-increment operator (i++), which returns the current value before incrementing the variable. In other words, you always call you function with the same i.
Using the pre-incremenet (++i) instead should solve the issue:
else (new Trainer(n)).workerTrain([data[i]], train(++i, trainingSet, l, y));
netTwo is not defined. nTwo is a parameter in the function and used in the first if clause. But the else if clause has an undefined variable named "netTwo." I therefore would expect a problem.
My objective is to populate an array dynamically using setInterval function. So I created a global variable array that I can access outside the scope of setInterval function. But when I try to do console.log, its empty.
However, if I try to do console.log inside the setInterval function, I can see the array populating every 1000 ms.
Its supposed to be a global variable so i should be able to see the variable right? How come it cannot be seen outside the function?
below is the code:
var array = [];
var n;
setInterval(function(){
n = Math.random();
if(n < 0.5){
array.push('white');
}else{
array.push('black');
}
// console.log(array); // i can see the array here
}, 1000);
console.log(array); // but i cannot see the array here
UPDATE:
Ok I now know the reason why its empty. So when I put a setTimeout of 5secs, I can now see the contents.
setTimeout(function(){
console.log(array); // i can now see the array!
}, 5000);
I'm pretty sure the array you "can't see" is actually displaying the correct array, an empty one. It gets called before the functions first array.push, so it shows up as empty.
Because you are using setInterval, with a 1 second delay, to add to the array the last line console.log(array); is executed before any of the interval function so the array would still be empty then.
Good info here: http://javascript.info/tutorial/settimeout-setinterval
setInterval schedules a function to be executed asynchronously. This means that the following code is executed first, finished, and only then, some time later, the scheduled function is started.
the reason why I cannot see the array is because theres not enough time for the console to log the contents so by putting another setInterval or setTimeout to delay the execution of console.log, I can now see the contents.
var array = [];
var n;
setInterval(function(){
n = Math.random();
if(n < 0.5){
array.push('meron');
}else{
array.push('wala');
}
// console.log(array); // i can see the array here
}, 1000);
setInterval(function(){
console.log(array); // i can now see the array!
}, 2000);
I wrote a function yesterday to count the number of "a" characters in a string. My teacher told me to refactor the code into a recursive function and I don't really know how to do so.
I would like some feedback on the subject, and by the way I'm an absolute beginner in JavaScript.
function numberOfA(n){
var numberA =0;
for (i=0; i<=n.length; i++){
if(n.charAt(i)== "a" ){
numberA++;}
}
return numberA;
}
to call the function following piece of code :
var n = prompt("type a word");
var output = numberOfA(n);
alert (output);
Thanks in advance !
The goal of recursion is to make a function which calls itself.
You might have mutual-recursion -- function A calls function B, calls function A... but that's certainly not needed here, and is better suited for when you know that you need to do two distinct things (one per function) and know that you need to do them in a leapfrog pattern.
Where recursion comes into play is when you're thinking about loops.
Normally, when you're doing things with loops, you might end up having two or three loops inside of one another.
Instead of worrying about managing loops, recursion is a way of thinking about what happens in a single-iteration of a loop, and writing ONLY the code needed to do that.
A really simple example of singular recursion might be to log all elements of an array to the console.
This is not a practical example -- it's a trivial example which has most of the pieces you need to make practical examples.
var array = [ "one", "two", "three", "four" ];
function listNextItem (array, index) {
var item = array[index];
if (!item) { return; }
console.log(item);
listNextItem(array, index + 1);
}
listNextItem(array, 0);
I've created a very simple function which looks like the inside of your innermost loop.
It sets an item variable, based on array[index].
If it doesn't exist, we're done, and we can return out of the function, so we don't try to go on forever (this is very important in recursion).
If it does exist, we log the item's value.
Then we call the exact same function, and pass it the exact-same array, but we pass it the value of index + 1.
Did this change anybody's life, or make loops obsolete?
Not really.
But it's the first step to getting recursion.
The next step is getting a return from recursion.
function recursiveAddOne (current, max) {
if (current === max) { return current; }
return 1 + recursiveAddOne(current + 1, max);
}
var total = recursiveAddOne(0, 3); // === 3 + 1 + 1 + 1
total; // 6
Normally in my return statement, I'd be sending the answer back to the variable in the outside world.
I'm still doing that, but here I'm adding a call to the same function, as part of my return.
What does that do?
Well, the outside function can't return a value until the inside function returns.
The inside function can't return a value until ITS inside function returns...
...and it goes all the way down until my termination-condition is met.
That condition returns a value to its outer function. That outer function returns that added value to ITS outer function... ...all the way up to where the outermost function gets handed the value of all of the other functions put together, and then returns THAT to the outside world.
It's like giving each Russian Matryoshka ("babushka") doll a piece of work.
You start with the biggest one, and go all the way inside to the tiniest one.
The tiniest one does its work first, and hands it back to the next one, which does its work and hands that back... ...all the way back until you're outside again.
Well, the basic concept of recursion is solving a problem with a smaller version of itself.
You have a function, numberOfA which gives you the length of a string(or maybe substring).
So let's say you have the string "javascript' the first string is at index 2.
It's logical to say that the number of as in your string is equal to 1 plus the number of as in the entire substring after the first a.
So what you do, is you add 1 to the number of as in the substring vascript
So here's some psudocode
function numA(str)
{
var substring = substr(index_of_first_a, str.length - index_of_first_a
return 1 + numA(substring);
}
function numberOfA(n, count){
if(!n.length) {
return count;
}
if(n.charAt(i)== "a") {
++count;
}
return numberOfA(n.substr(1), count);
}
var numberA = numberOfA('asdfafeaa', 0);
Try this:
function numberOfA(n) {
return n == "" ? 0 : (n.charAt(0) == "a" ? 1 : 0) + numberOfA(n.substring(1))
}
Here's how it works:
If n is the empty string, return 0 and finish the recursion. This is the base case of the recursion.
Else if the character at the first position in the string is an "a" add one, if not add zero and either way advance the recursion by removing the first character from the string. This is the recursive step of the recursion.
As you can see, every recursive solution must have at least a base case and a recursive step.
<!DOCTYPE html><html lang="en"><body><script>
var foo = function foo() {
console.log(arguments.callee); // logs foo()
// callee could be used to invoke recursively the foo function (e.g. arguments.callee())
}();
</script></body></html>
arguments.callee function will call the currently being executed method.