JavaScript recursive function using ternary operator - javascript

why is it necessary to add return statement before ternary operator in recursive function to return function output?
// This dose not work
function rec(n) {
n == 1 ? n : n + rec(n - 1);
}
// This works as return statement is added before ternary operator
function rec(n) {
return n == 1 ? n : n + rec(n - 1);
}
// This works
function rec(n) {
if (n == 1) return 1;
return n + rec(n - 1);
}

// If you would like to do this in one line then correct solution would be:
let rec = n => n == 1 ? n : n + rec(n - 1);
// Now you dont need to add the return keyword before
// This works as return statement is added before ternary operator
function rec(n) {
return n == 1 ? n : n + rec(n - 1);
}
// This works
function rec(n) {
if (n == 1) return 1;
return n + rec(n - 1);
}

A recursive function is function which calls itself during the execution. The ternary operator decides if the function need to call itself. So the return statement call the same function.
In the example n == 1 ? n : n + rec(n - 1); if n=1 then the function should return the value of n if not then the function will call itself with new value that is n-1.

You need a return because of
n + rec(n - 1);
where the rec(n-1) call needs to return a value to be able to calculate n + rec(n - 1), and that goes for each call to rec() until n reaches 1 when it just returns 1.

return is never default in ternary operation.
return is default in Arrow-function but it not default in normal function deceleration.
to return a output from a normal function execution it is always necessary to add return statement, but it is optional in case of Arrow-function.
function x() { 5;}
console.log(x()); // Opuput: undefined
let y = () => 5;
console.log(y()); // Output: 5

A conditional expression (often called a ternary) is simply an expression. It yields a value, but it doesn't do anything with it. In fact, unless it has side-effects, it's totally useless unless you either:
return it from a function,
assign its result to a variable, or
nest it in another expression in which you do one of these things
You may be confused by the fact that arrow functions with single-expression bodies return the result of that expression. It's still being returned by the function, even though you don't explicitly use return. And because of this simplicity, conditional expressions are often used as the body of arrow function.
But it should be no more surpising that you have to have return here than that you have to have it in
function add (x, y) {
return x + y;
}
If you took out the return there, the addition will still happen when the function is invoked, but it won't yield any value. It's the same thing in your original.

Related

I've got a problem with recursion in my code [duplicate]

I need help creating the code to find the factorial of a number. The task is to
Create a variable to store your answer and initialize it to one
Create a loop that beings at the given value, fact
Check if fact is one or zero
multiply fact with your answer variable
At the end of the loop decrease fact
Print answer using console.log
The pseudocode is
while(factorial)
if factorial == 0 or factorial == 1
break
result => result * factorial
factorial => factorial - 1
My code below isn't complete because I'm confused by the pseudocode.
function nth_fact(nth){
var a = 1
while(nth_fact)
if (nth_fact == 0 || nth_fact == 1){
break;
result => result * nth_fact
nth_fact => nth - 1
console.log()
}
}
At first lets examine what went wrong:
var a = 1
What is a? Its definetly not a good name for a variable. Maybe name it to result ? The same applies to nth which should be named factorial and nth_fact which should rather be factorize or sth. You should also always use ; to end a statement.
while(nth_fact)
As your while loop contains multiple statements (the if and the two assignments) you need to open a block here by using { right after the condition. nth_fact refers to the function, you rather want to take factorial here.
if (nth_fact == 0 || nth_fact == 1){
break;
Now you open a block statement for the if, but you never close it. So you need another } after the break.
result => result * nth_fact
nth_fact => nth - 1
console.log()
=> is the arrow function expression, but you want the assignment operator =. Also you need to pass something to console.log, e.g. console.log(result)
All together:
function factorize(factorial){
var result = 1;
while(factorial){
if (factorial == 0 || factorial == 1){
break;
}
// ?
factorial = factorial - 1;
console.log(result);
}
return result;
}
That pseudocode is indeed confusing, because what it calls factorial is actually not the factorial -- it's the current value, which the result (which is actually the factorial we're looking for) is multiplied by. Also, if is superfluous, because while already checks for the same condition. So the correct pseudocode would be
currentValue = argument
factorial = 1
while (currentValue > 1)
factorial = factorial * currentValue
currentValue = currentValue - 1
// now, 'factorial' is the factorial of the 'argument'
Once you get this sorted out, here's a bonus assignment:
create a function range(a, b) that creates an array of numbers from a to b. For example, range(5, 8) => [5, 6, 7, 8]
create a function product(array) that multiples array elements by each other. For example, product([2, 3, 7]) => 42
write the factorial function using product and range
I solve this this way
function factorial(number) {
let num = 1;
let result = 1;
while (num <= number) {
result = result * num;
num++;
}
return result;
}
const myNumber = factorial(6);
console.log(myNumber);
function factorial(num) {
var result = 1
while (num) {
if ((num) == 0 || (num) == 1) {
break;
} else {
result = result * num;
num = num - 1;
}
}
return `The factorial of ${val} is ${result}`
}
let val = prompt("Please Enter the number : ", "0");
var x = parseInt(val);
console.log(factorial(x));
A Short And Clean Code is :
let number = 5;
let numberFactorial = number;
while(number > 1){
numberFactorial = numberFactorial * (number-1);
number--;
}
console.log(numberFactorial);
function factorize(factorial) {
if(factorial == 0 | factorial == 1) {
return 1
}
else{
var result = factorial;
while(factorial >= 1 ){
if(factorial-1 == 0) {
break
};
result = result * (factorial - 1);
factorial = factorial-1;
//DEBUG: console.log(factorial + ' ' + result);
};
return(result);
}
}
If you want more info about functions, can see in my GitHub, good learning!
Github: https://github.com/bennarthurdev/JavaScript/tree/main/FUNCOES
You used the right approach. Just the syntax was wrong. Here it is:
function nth_fact(nth){
var result = 1 ;
while(nth){
if ((nth) == 0 || (nth) == 1)
break ;
result = result * nth;
nth = nth - 1
}
console.log(result);
return result;
}

why does this function not work? I want it to count backwards from 10 to 1

I want it to count backwards from 10 to 1.
function countdown(n) {
if (n < 1) {
return []
} else {
return countdown(n - 1).unshift(n);
}
}
The value returned by the function isn't an array. unshift has to be used only on array objects. There's many much simpler way to achieve what you are trying to do here.
I have mentioned a simple recursive function which achieves the same -
function countdown(n) {
console.log(n)
// recursive till n becomes zero. When n === 0, just return 0
return n ? countdown(n - 1) : 0;
}
countdown(10)
NOTE : The method you are using - unshift() returns new length property of the object upon which the method was called. So, if you want to have a countback array to be returned from the function, you could choose to use the following approach which uses recursion and unshift(), just as in your code with slight changes in code -
function countdown(n) {
if (n < 1) {
return []
} else {
let z = countdown(n - 1);
z.unshift(n);
// return the array itslef so unshift() would work. Directly returning z.unshift would result in returning a number and not an array.
return z;
}
}
// will return countdown array
console.log(countdown(10))
There will probably be a better way to do this without using unshift() or recursion...but I have just shown an approach which can be used to achieve the desired result.
unshift works on arrays. n is a number.
function countdown(n){
if (n < 1) {
console.log(n)
return n
} else {
console.log(n)
return countdown(n-1);
}
}
countdown(10)

How to visually conceptualize this Javascript recursive function?

I want to visually understand what happens when this recursive code is run. I don't understand how the end result is 9.
In my mind, the f(x - 1) will iterate until it returns 5, then you add 1 which equals 6.
let f = x => {
if (x === 0) {
return 5
}
return 1 + f(x - 1)
}
let y = f(4)
console.log(y)
Thank you for your time
You have the reasoning backwards. It isn't that one gets added once at the very end, one gets added after each resursive call returns. Think about this line:
return 1 + f(x - 1)
Once the recursive f call returns, one is added to that result. Then this recursive call returns, and one is added again. That keeps happening until the initial call returns.
Since one is added once per recursive call, and it will recurse four times, and the base case returns 5, this function ends up basically just calculating
1 + 1 + 1 + 1 + 5 == 9
You could take a level for an indention of a log and look which level has an input and return value.
function f(x, level = 0) {
console.log(level, '>>'.repeat(level + 1), x);
var v = x === 0
? 5
: 1 + f(x - 1, level + 1);
console.log(level, '<<'.repeat(level + 1), v);
return v;
}
console.log('result', f(4));
.as-console-wrapper { max-height: 100% !important; top: 0; }

I don`t understand recursion in JavaScript

I don't understand this!
function rec(arg){
console.log(arg);
if(arg == 3)
return arg;
else
rec(arg + 1);
}
var i = rec(0);
console.log(i);
//0
//1
//2
//3
//undefined
Why inside the function 'arg' has a value but when it`s time to return it('arg == 3') it gives me 'undefined'?
Here is another one
function power(base, exponent) {
console.log(exponent);
if (exponent == 0)
return 1;
else
return base * power(base, exponent - 1);
}
console.log(power(2, 3));
//3
//2
//1
//0
//8
Why does it return '8' when 'exponent' is '0' inside the function and it should return '1'!
I now understand that I don`t understand how JS works.
In your first example, you should write the line
if(arg == 3)return arg;else rec(arg + 1);
as this
if(arg == 3)return arg;else return rec(arg + 1);
In the second example, you should change the line
return base * power(base, exponent - 1);
to
return Math.pow(base, exponent);
(actually, you should just replace the whole function with a call to pow(), you don't need to re-write it)
EDIT:
In the first example, you should have broken it town into multiple lines, then you would have seen it as a simple mistake. So, like this:
if(arg == 3)
return arg;
else
return rec(arg + 1);
And for posterity and good habits, it should be like this (in other words, use brackets)
if(arg == 3) {
return arg;
}
else {
return rec(arg + 1);
}
In your second example, you used recursion when you shouldn't have. A simple call to Math.pow() was all that you needed. Unless you wanted to log the behavior, no need to re-write the function.
EDIT:
My mistake after reading your comment. I apologize.
The flow goes like this:
console.log(power(2, 3));
then to the line
if (3 == 0)
return 1;
else
return 2 * power(2, 3 - 1); //power() returns 4, we return 8
//same as: return 2 * power(2, 2);
then to the line
if (2 == 0)
return 1;
else
return 2 * power(2, 2 - 1); //power() returns 2, we return 4
//same as: return 2 * power(2, 1);
then to the line
if (1 == 0)
return 1;
else
return 2 * power(2, 1 - 1); //power() returns 1, we return 2
//same as: return 2 * power(2, 0);
then to the line
if (0 == 0)
return 1;
else
// moot
Because your not telling it to.
function rec(arg){
console.log(arg);
if(arg == 3)return arg;
else rec(arg + 1); // < --- not a return statement
}
var i = rec(0);console.log(i);
The else block is not a return statement.
And as for your second question, that is because the 0 is coming from a nested call to the function somewhere down the line:
base * power(base, exponent - 1); // power(base, exponent - 1) would return 1 here, and base is probably 8 at that moment, so 8 * 1 would return you 8
While the previous answers give factually correct information, they don't address what you're misunderstanding.
In both cases, you're expecting the return form the recursive function to be the return of the last (innermost) invocation. That's incorrect.
The return from the innermost invocation is given to the second-to-innermost invocation; and then this continues until finally the outermost invocation returns. Only the outermost invocation's return value is seen by the caller.
So in the first example, you call rec(0).
Then rec(0) calls rec(1),
which calls rec(2),
which calls rec(3).
Then rec(3) returns the value 3 to rec(2) (because that's still running).
Then rec(2) exits without a return to rec(1)
which exits without a return to rec(0)
which exits without a return to the caller.
So the caller sees the return as undefined.
In the second case, yes, the last invocation of power() is power(2,0) which returns 1... to the running invocation of power(2,1)
which returns 2 to the running invocation of power(2,2)
... and so on until the final return seen by the caller is 8.
By the way, this is not "recursion in JavaScript". This is recursion.

Underscore .reduce() returns NaN?

Should add all the natural numbers below 1000 that are multiples of 3 or 5.
var sum = _.reduce( _.range(1, 1000), function(x, n) {
if (n % 3 == 0 || n % 5 == 0) { return x+=n; }
}, 0);
I expect the output to be 233168 but I get NaN.
For some reason sum is not accepting the initialized value of 0. However if I preface this with var sum = 0; then it works and returns the proper output of 233168
Why doesn't it accept the initialized value?
The problem is the reducing function returns undefined when the conditional fails .. thus x evaluates to undefined (the last return value) in the subsequent invocation .. and undefined + a number is .. well, NaN.
Also, reduce is being used incorrectly; it should carry its own state. Compare it with:
var sum = _.reduce( _.range(1, 1000), function(x, n) {
// Add n to the tally if it is a valid multiple..
// (the returned value is used as the *next* value of x)
if (n % 3 == 0 || n % 5 == 0) { return x + n; }
// ..or simply return the current tally.
else { return x; }
}, 0);
Note that the sum variable was not assigned from within the reducing function (it would have been overwritten by the outside assignment anyway). This keeps reduce a pure operation, not withstanding the occasional abuse of a mutable memo, truer to its functional roots.

Categories