Can't acces the global variable using RECURSION - JavaScript - javascript

Hello people I'm new to Javascipt.
Trying to print Fibonacci in Reverse by Recursion. example: RevFib(5) => 3,2,1,1,0
here is the code which works fine.
function fibo(n, a, b)
{
if (n > 0) {
// Function call
fibo(n - 1, b, a + b);
// Print the result
console.log(a);
}
}
fibo(5,0,1);
this works fine. but I don't want to output on console. instead I wanted to return a array contain all fibonacci numbers in reverse like [3,2,1,1,0].
I tried to implement it using defining a global array then try to passing that array in fibo() function. It doesn't work. don't know why.
here is the array code:
var arr = [];
function fibo(n, a, b, arr)
{
if (n > 0) {
// Function call
fibo(n - 1, b, a + b, arr);
// Print the result
console.log(a+' - '+arr);
arr.push(a);
}
}
fibo(5,0,1);
the output is error:
Uncaught TypeError: arr is undefined
as a newbie in JS. I can't get what went wrong. someone tell whats wrong here. Thanks

You're naming a function parameter called arr. Did you mean to do call fibo like so?:
function fibo(n, a, b, arr) {
if (n > 0) {
fibo(n - 1, b, a + b, arr);
console.log(a + ' - ' + arr);
arr.push(a);
}
}
let arr = [];
fibo(5, 0, 1, arr);
You also don't need arr to be a global variable if you're going to pass it as a function argument. Generally you should avoid globals (unless you have a special use case), because they make code harder to maintain. Passing the array to the fibo function is the right idea.
You could even have a wrapper function to make usage of return types.
function fiboRecurse(n, a, b, arr) {
if (n > 0) {
fiboRecurse(n - 1, b, a + b, arr);
console.log(a + ' - ' + arr);
arr.push(a);
}
}
function fibo(n) {
let arr = [];
fiboRecurse(n, 0, 1, arr);
return arr;
}
console.log(fibo(5));

You are naming a function parameter "arr" as well. The global variable will therefore not be accessible.

You were almost there with your own code. A few tweaks and it runs smoothly:
function fibo(n, a=0, b=1, arr=[]){
if (n > 0) {
fibo(n-1,b,a+b, arr);
arr.push(a);
}
return arr
}
const res=fibo(6);
console.log(res)
I used "optional arguments" in the function definition. If they are omitted at calling time they will have the values given in the function definition.

Related

returning an array using recursion

I'm pretty new to recursion and Im having trouble returning the value I want into an array. I have a simple function called countDown which needs to take in an argument of type integer in this case the parameter/argument is the letter (n). and I want to count backwards starting from the number (n) all the way to 1. so for example if I pass in the number 4 I would like to return [4, 3, 2, 1] and I need to do this recursively. I believe I have gotten close because in my code I simply put a console.log(n) and I can see now the numbers are printing out 4, 3, 2, 1 however I need to return these numbers in an array and I am pretty lost. I'm familiar with .push() but that doesn't seem to work and I have tried .concat() but I'm not able to get it to work either. Any help is much appreciated!
function countDown(n) {
if (n < 1) {
return [];
} else {
console.log(n);
let j = countDown(n - 1);
}
}
countDown(4);
You are indeed pretty close. There are going 2 things wrong in your snippet.
You do not return a value if n is not smaller than 1 (the else scenario).
You do log n, but don't add it to the result.
Without changing a lot, a solution might look like this:
function countDown(n) {
if (n < 1) {
return [];
} else {
// get the countdown of n - 1
const ns = countDown(n - 1);
// add the current n in front
ns.unshift(n);
// return the list
return ns;
}
}
console.log(countDown(4));
Make sure you return something in every case!
You're doing it for the base case (return []), but you need to return something that includes the recursive call in other cases (return // something that uses countDown(n-1)).
function countDown(n) {
if (n < 1) return [];
return [n, ...countDown(n-1)];
}
console.log(countDown(4));
You appear to be nearly there, but when using recursion state will need to be passed to the next iteration.
So below is an example where the arr parameter if left blank will create the initial array, and then the recursive part can just keep passing this down.
function countDown(n, arr) {
if (!arr) arr = [];
if (n < 1) {
return arr;
} else {
arr.push(n);
return countDown(n -1, arr);
}
}
console.log( countDown(4) );
Is this does what you want?
let arr = [];
function countDown(n) {
if (n < 1) {
return [];
} else {
arr.push(n);
countDown(n - 1);
}
}
countDown(4);
console.log(arr);
Try something like this
function countDown(n, a = []) {
if (n < 1) {
console.log(a);
return a;
} else {
a.push(n);
let j = countDown(n - 1,a);
}
}
countDown(4);

JavaScript Object Sort method

In the compareNumeric fn I dont understand this concept with comparison.
To see more detailed: if (5 > 3) return 1; So what is this return 1 and return -1; how does it work, and how does it affect on sort method. Please , help me out!
function compareNumeric(a, b) {
if (a > b) return 1;
if (a < b) return -1;
}
var arr = [ 1, 2, 15, 14, 66, 434, 112, 3 ];
arr.sort(compareNumeric);
alert(arr); // sorted array
MDN's documentation for Array.prototype.sort will help. Basically, sort calls the callback repeatedly, with various combinations of two entries from the array. The callback's return value tells sort whether 1) a should be before of b in the result (by returning a negative value), or 2) a should be after b in the result (by returning a positive value), or 3) a and b are equivalent for sorting purposes so it doesn't matter (by returning 0).
Your example compareNumeric has a bug: It should return 0 if a is neither < nor > b, but instead it doesn't return anything, so calling it results in undefined. Instead:
function compareNumeric(a, b) {
if (a > b) { return 1; }
if (a < b) { return -1; }
return 0;
}
But, it has another problem: It never checks whether a and b are actually numeric. If the author is happy to assume they're numeric, it can be a simpler function:
function compareNumeric(a, b) {
return a - b;
}
If both a and b are numbers, then a - b will be negative if a is less than b and so should be before it in the result, positive if a is greater than b and so should be after it in the result, or 0 if a and b are equal.
Note that the number of times the callback gets called and in what order are not defined by the specification; all it says is that Array#sort will call the callback as necessary and use the resulting information.
Let's watch what arguments Array#sort gives with your example; again note that this will be implementation-dependent:
function compareNumeric(a, b) {
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
var arr = [ 1, 2, 15, 14, 66, 434, 112, 3 ];
arr.sort(function(a, b) {
var result = compareNumeric(a, b);
console.log("a = " + a + ", b = " + b + "; returning " + result);
return result;
});
console.log(arr.join()); // sorted array
.as-console-wrapper {
max-height: 100% !important;
}

Declare variables and return value in one statement in javascript

In many functions I have noticed the following pattern: function declares variables, combines it to the result and returns result. It is shown in this very simple example:
function fn() {
var a = 1,
b = 2;
return a + b;
}
fn(); // 3
or:
function fn() {
var a, b;
return a = 1,
b = 2,
a + b;
}
fn(); // 3
I would like to minimize this code and reduce it to the one statement. It could look like this:
function fn() {
return a = 1,
b = 2,
a + b;
}
However this code declares variables a, b in global scope which is not acceptable. Is it possible to do this in javascript?
Maybe this works for you, which is not advisable because of using assignment alogn with the comma operator.
function fn(a, b) { // declaration in local scope
return a = 1, b = 2, a + b; // return value with comma operator
}
A newer approach takes default values and returns just the addition of both.
fn = (a = 1, b = 2) => a + b;
What you are trying to do (declare using var and return in same statement) is not possible with JavaScript syntax.
The most concise you can get is your first option:
function fn() {
var a = 1,
b = 2;
return a + b;
}
fn(); // 3

javascript how to pass function results into the same function along with a value from array

I have a function called findLCM, which takes 2 arguments (a,b).
I also have an array with an unknown number of elements (all numbers). For the purpose of explanation let's say:
var values = [c, d, e, f]
now what I need to build is this:
var result = findLCM(findLCM(findLCM(c,d),e),f);
I tried to write a for loop that would do this, but got stuck and can't figure it out. Can somebody point out the correct way to do this?
My code so far:
var result = 0;
for(f = 0; f < values.length -2; f++) {
result *= findLCM(findLCM(values[f], values[f+1]),values[f+2]);
}
This sounds like a good case to use Array.prototype.reduce():
var values = [c, d, e, f];
var lcm = values.reduce(function(previous, currentValue, currentIndex, arr) {
return findLCM(previous, currentValue);
});
alert(lcm);
I think that what you are looking is to use reduce.
var findLCM = function(a,b) {
...
};
var result = [a, b, c, d, e].reduce(findLCM);
try this recursive function
function findLCMArray (arr)
{
if ( arr.length > 2 )
{
return findLCM( arr.shift() , findLCMArray (arr) );
}
else
{
return findLCM( arr.shift(), arr.shift() );
}
function findLCM( x, y )
{
//logic to do LCM
}
}
Or you can loop through like this
var arr = [2,4,6,8];
var lcmValue = arr[0];
arr.forEach ( function(value){
lcmValue = findLCM( lcmValue, value);
} );
alert(lcmValue);

Why would a return be undefined but console.log return an int?

So I have the following function:
var multiplyT = function(a, b, acc) {
if (b == 0) {
console.log("BASE CASE: ", acc);
return acc;
} else {
b--;
acc = acc + a;
console.log("NOT THE BASE CASE: ", a,b,acc);
multiplyT(a, b, acc);
}
}
It gets called with:
console.log(multiplyT(5,3,0));
And gives this:
NOT THE BASE CASE: 5 2 5
NOT THE BASE CASE: 5 1 10
NOT THE BASE CASE: 5 0 15
BASE CASE: 15
undefined
As output. What I am confused about is why acc would give the correct value for the console.log but be "undefined" according to what is returned.
In your else block, it should be return multiplyT(a, b, acc);
This is a good one. Recursion can make your head spin. The reason it's undefined is because not all iterations return a value, and for those that don't you get undefined -- the same as if you set a variable to any function that doesn't return a value.
It gets confusing with recursion though, because the return value you're seeing in this case is from the first-called and last-completed iteration. Unlike a regular method call where return breaks execution of the method -- sending it back to from wherever it came, recursion still has wind its way back through the call stack, returning whatever values it has to give back, including undefined, in the reverse order in which they were called. So it's actually giving your console.log call four return values: 15, undefined, undefined, undefined.
Because it synchronous, console.log can't execute until the method it called is done. What it outputs is the last value it gets, or undefined. If you stick in a return after the method call in your else block, you'll see you get 5, or the value of acc after the first iteration of the function.
var multiplyT = function(a, b, acc) {
if (b == 0) {
console.log("BASE CASE: ", acc);
return acc;
} else {
b--;
acc = acc + a;
console.log("NOT THE BASE CASE: ", a,b,acc);
multiplyT(a, b, acc);
return acc;
}
}
console.log(multiplyT(5,3,0));
You need to return from the else block as well.
In your case even though the value of acc is updated that value is mot returned when b != 0
var multiplyT = function(a, b, acc) {
if (b == 0) {
console.log("BASE CASE: ", acc);
return acc;
} else {
b--;
acc = acc + a;
console.log("NOT THE BASE CASE: ", a, b, acc);
return multiplyT(a, b, acc); //return here
}
}
console.log(multiplyT(5, 3, 0));
You're calling recursively the multiplyT function, but you're not controlling the return. Then, multiplyT(5,3,0) does not return a value in the first call and the function then returns undefined.
It's true that the stack is executing, but the first call is the more important: it needs to get the value from the recursive inner function that returned the final value.
Fix the code in the else branch so you can return the recursive call:
var multiplyT = function(a, b, acc) {
if (b == 0) {
console.log("BASE CASE: ", acc);
return acc;
} else {
b--;
acc = acc + a;
console.log("NOT THE BASE CASE: ", a,b,acc);
return multiplyT(a, b, acc);
}
}
I've come up with a good solution to this while working on one of my projects in which I traverse a complex JSON object to return some data on searching for the id.
var multiplyT = function(a, b, acc) {
if(b == 0) {
console.log("BASE CASE : ", acc);
return acc;
} else {
var ret;
b--; acc += a;
console.log("NOT THE BASE CASE: ",a,b,acc);
while( ret = multiplyT(a,b,acc) ) {
return ret;
}
}
}
Here, we run a while loop to see if the recursed function call returns a true value or undefined. If returns something other than undefined, it will return the data.

Categories