Writing recursive functions - Eloquent JS - javascript

I'm trying to write a function that checks if a number "N" is even or odd by subtracting 2 until it gets to 1 or 0. A final value of 0 represents even. The goal here is to use a recursive function to reach the final result, but I'm having some issues where all I have returned are undefined.
This is what I have so far.
function isEven(number) {
function subTwo(number) {
if (number == 0) {
return true;
}
else if (number == 1) {
return false;
}
else if (number > 0) {
number -= 2;
subTwo();
}
else {
console.log("bruh");
}
};
};
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-1));
// → ??
Does anyone see what I'm doing wrong or have any advice for me?
Thanks.
EDIT:
Thanks for the help guys. It was suggested that I remove subTwo completely and use isEven as the recursive function, and that I had to use return isEven(number) within the second if/else statement.
Both of those suggestions together helped the code compile correctly.
Thanks a ton guys, although I'm not sure why I got downvoted lol.

Your problem is here:
subTwo();
You need to pass the current version of number into it: subTwo(number); and return it.
you could also fix the problem by omitting the parameter in the internal function, like so: function subTwo(){...} The internal function already has access to the parent function's parameter (closure), so you don't need to pass that into the internal one.
also, this is not returning anything, it's just logging. JavaScript always returns something. If you don't say return "something", it returns undefined.
else {
console.log("bruh");
}
Personally, I would also rework you code like so:
function subTwo(number) {
if (number > 0) {
number -= 2;
subTwo();
}
else if (number == 1) {
return false;
}
else if (number == 0) {
return true;
}
else {
console.log("bruh");
}
};
The statements are then in descending order, so you can quickly see the progression. It helps people look and see if anything has been missed.

The problem is that you define the function subTwo but it's never actually called when isEven is called. A simpler version would be to not even have another function and do it all with recursive calls of isEven
function isEven(number) {
if (number === 0) {
return true;
} else if (number === 1) {
return false;
} else {
return isEven(number - 2)
}
}
EDIT
Alternatively, if you really want the additional function, notice that you defined subTwo to take in a parameter but you did not pass in the parameter when recursively calling it via subTwo();. Also, when you recursively call subTwo(number), make sure you actually have return subTwo(number) so the value is returned at each recursive call. Additionally, you need to actually call the function and return the result when isEven(number) is called via a return statement and wrapping the function in brackets and calling it with number or manually calling it using return subTwo(number). See below for an example of how you would return at each stage so it passes it all the back up to the original call of isEven(number):
function isEven(number) {
return (function subTwo(number) {
if (number === 0) {
return true;
}
else if (number === 1) {
return false;
}
else if (number > 0) {
number -= 2;
return subTwo(number);
}
else {
console.log("bruh");
}
})(number);
};

As was said in the comments you never check for a value less than 0. What happens is when you enter the value -1 is it jumps down to the else part of your code. The part that says "console.log("bruh");" After completing that line the program keeps going and returns... nothing. You dont return anything, hence why you get undefined. You should set up your code to handle the case when a negative number is passed in.

Related

Best practice for returning value

I have often wondered if it is bad practice to allow sequential execution to decide the return value and termination point. EG (this is a question surrounding IF statements, so ignore the fact there are myriad better ways to do this simple function!):
function isGreaterthanTen(val) {
if(val > 10) return true;
return false;
}
Same effect, is smaller but maybe less readable than:
function isGreaterthanTen(val) {
if(val > 10) {
return true;
} else {
return false;
}
}
So is one better than the other, best practice wise and/or min-wise?
You should avoid writing so called spaghetti code. That means, one should be able to read your code without jumping from one place to another in order to untangle and understand it. Having return statement in the middle of your code can be considered a spaghetti code, especially in longer functions.
I prefer having one return statement that returns a variable, which I declare at the top of the function and manipulate throughout the execution.
function isGreaterthanTen(val) {
let isGreater = false;
if (val > 10) {
isGreater = true;
}
return isGreater;
}
of course that function can be shortened to:
function isGreaterthanTen(val) {
return val > 10;
}
A one exception from this rule which I'd allow is at the top of the function when you validate the data and prevent the execution:
function isGreaterthanTen(val) {
if (typeof val !== 'number')
return;
return val > 10;
}
which fill return nothing if the parameter isn't a number.
At my current work - Leads never advise to use single line execution without brackets stating readability lacks there.
if(true) {
return 'good practice'
}
if(true)
return 'bad practice'
Another related point I always follow is checking for negative value first
if(false) {
return 'this is the negative case'
}
return 'case for most of the positive case'
However I know different ways to just handle such single line returns
If just boolean than you can simply return the condition
function foo(){
return 1 === 1
}
console.log(foo())
You can use coerced value for just boolean value if your value is treated as truthy or falsy and not a boolean
function foo() {
return !!1 // 1 treated as true
}
console.log(foo())
If you have two different values to get returned so you probably use ternary too.
function foo() {
const me = 'satyam',
friend = 'jack',
satyamAge = 23
return satyamAge === 20 ? me : friend
}
console.log(foo())

What is the difference between using `return` outside and inside of conditions?

What is the difference between using return in outside of else condition and inside of else condition?
I know the best code is without use else and I know both are doing similarly same. Is there difference or advantages?
function f1() {
if (1 == 1) {
return true;
} else {
return false;
}
}
function f2() {
if (1 !== 1) {
return true;
} else {
return false;
}
return false
}
console.log(f1());
console.log(f2());
Not related to your previous question, but only this:
In Method:2, the last return statement (ie return true;) is virtually useless. Because last line in the SaveVersionMainScreen() won't be executed as there is if and else both conditions are present. Which should account for all cases.
if you have if statement within block code and contains return in both if and else block. Its mean either if block will execute and return from method or else block will execute and return. Other statements below that blocks will not execute and compiler may give you error something like
Statements cannot be reached
For Example:
SaveVersionMainScreen() {
let element = this.commonValidation(true);
if (element) {
return false;
}
else{
return true;
}
// Below statements will never run
var a=2;
var b=3;
var c=4;
return true;
}
Way to go changing you question completely. Leaving my answer anyway for now.
Your version 2 is bad practice, code would not work in a strict language like Java as you have a return statement that cannot be reached. As for your test removing the else from your function should solve it for you, but the issueseems to be with the test and not your code.
SaveVersionMainScreen() {
let element = this.commonValidation(true);
if (element) {
return false;
}
return true;
}

Differentiate between an initial and successive call to a recursive function

My broad question is what's the simplest way to differentiate between an initial and successive call to a recursive function in JavaScript.
Lemme give an example...
Let's say I want the following function to return false if the string passed to the function in the initial call is empty. Is there a way to do this without adding in another parameter to the function?
function isPalindrome(str) {
if (str.length <= 1) {
return true;
}
if (str.charAt(0) !== str.charAt(str.length -1)) {
return false;
}
return isPalindrome(str.substr(1, str.length - 2));
}
isPalindrome('') // returns true, but I want this to return false
Btw, I know the above function could be written more simply as:
function isPalindrome(str) {
return str == str.split('').reverse().join('');
}
But I'm reframing it as a recursive function to get at the broader question here...
Don't try to distinguish different calls - the result of the function should not depend on side effects and definitely not on the call stack.
Instead, use a second function that does a little different thing:
function isPalindrome(str) {
return str.length <= 1 ||
str.charAt(0) == str.charAt(str.length-1) && isPalindrome(str.slice(1, -1));
}
function isNonEmptyPalindrome(str) {
return str.length > 0 && isPalindrome(str);
}
You can have a nested function, even with the same name:
function isPalindrome(str) {
// The code out here is for the initial call:
if (str === '')
return false;
// Then do the recursive call
return function isPalindrome(str) {
// within this scope, isPalindrome refers to this function
if (str.length <= 1) {
return true;
}
if (str.charAt(0) !== str.charAt(str.length -1)) {
return false;
}
return isPalindrome(str.substr(1, str.length - 2));
}(str); // call this function immediately
}
For a general form:
function name(arg) {
// Setup code before initial call
//////////////////////////////
var retVal = function name(arg) {
// recursive routine code
}(arg);
// Cleanup code after recursion completes
/////////////////////////////////////////
return retVal;
}
Demo using factorial
This is essentially the same as Bergi's answer but with the helper function declared inside isPalindrome so that it isn't used elsewhere.
A better example for a palindrome is that all punctuation should be removed and letters made all upper or lower case (so that comparisons are not case sensitive), but only on the first call. After that, it's a simple matter of comparing characters.
The length == zero part is also only handled once, the function isn't called recursively if there are no characters left to compare.
The following does initial processing, then calls an inner function.
A function declaration is used instead of a named function expression as the latter have undesirable side effects in IE.
function isPalindrome(s) {
// Initial processing only on first call
// remove all punctuation
s = s.replace(/[^a-z0-9]/ig,'').toLowerCase();
return s.length == 0? false : doCheck(s);
function doCheck(s) {
if (s.length > 1) {
if (s.substr(0,1) == s.substr(s.length - 1, 1)) {
s = s.substr(1, s.length - 2);
return s.length? doCheck(s) : true;
} else {
return false;
}
}
return true;
}
}
console.log(isPalindrome("Madam I'm Adam")); // true
console.log(isPalindrome("Madam I'm Addam")); // false

return true, breaks code in javascript

Having the following code:
function test(x) {
if(x=='a') return false;
return true;
}
if(y ==x) {
return test('a');
group['ids']= inputs.val();
console.log(group);
}
why return true simply breaks my code by not continuing beyond the return?
Note: I want the return test()'s answer to control if either it should continue with the code OR not
Update
I already do something like:
var response = test('b');
if (response==false) return false;
... more code here ...
But I want to avoid having to do so on every invoke of that function
Because that's what return does in almost every programming language: it
exits the function and
returns a value
If you need other code to be executed, put it before the return statement.
Edit: I saw your edit, but it doesn't change the very nature of return in that (and every) context. It will continue to stop the flow of the current scope, returning to the nearest higher scope with a value (in your case, true or false).
The keyword return, as it name suggests, returns the program flow control to the calling function and optionally sets the function's return value.
This works the same way in every C-like language.
What you probably wanted to do is a Delphi-like approach, where the keyword Result works differently - it just sets the return value that will be used when the function terminates, but does not immediately terminate the function.
function() {
var result = someDefaultValue;
if (someCondition)
result = otherValue;
if (otherCondition)
result = yetAnotherValue;
return result;
}
try putting return at the end because return true will break the execution and nothing will execute after that
When a return statement executes, the execution of the current function ends, and control of the program is returned to the context that invoked the function. Anything after a return statement will not be executed.
The return keyword causes a function to end ('return') when the interpreter reaches that keyword and does not continue to process anything after the return statement (in that same function).
You could rewrite what you have:
group['ids']= inputs.val();
console.log(group);
return true;
I typically find out which scenarios are bad/errors and return false; out of them, THEN continue on to the code which is correct.
function Testmcdooder (test) {
if (test === false) {
// just exit up here
return false;
}
// now all of this code will run only if we're fine
group['ids']= inputs.val();
console.log(group);
}
The return statement exists from the function. I think that you rather want an if statement:
if (y == x) {
if (test('a')) {
group['ids']= inputs.val();
console.log(group);
}
}
If you also want to return the value after determining if the other statemens should run:
if (y == x) {
if (test('a')) {
group['ids']= inputs.val();
console.log(group);
return true;
} else {
return false;
}
}
Alternatively:
if (y == x) {
var cond = test('a');
if (cond) {
group['ids']= inputs.val();
console.log(group);
}
return cond;
}

Stopping a JavaScript function when a certain condition is met

I can't find a recommended way to stop a function part way when a given condition is met. Should I use something like exit or break?
I am currently using this:
if ( x >= 10 ) { return; }
// other conditions;
Return is how you exit out of a function body. You are using the correct approach.
I suppose, depending on how your application is structured, you could also use throw. That would typically require that your calls to your function are wrapped in a try / catch block.
use return for this
if(i==1) {
return; //stop the execution of function
}
//keep on going
The return statement exits a function from anywhere within the function:
function something(x)
{
if (x >= 10)
// this leaves the function if x is at least 10.
return;
// this message displays only if x is less than 10.
alert ("x is less than 10!");
}
Use a try...catch statement in your main function and whenever you want to stop the function just use:
throw new Error("Stopping the function!");
throwing the exception when the condition is met to break the function.
function foo() {
try {
if (xyz = null) //condition
throw new Error("exiting the function foo");
} catch (e) {
// TODO: handle the exception here
}
}
Try using a return statement. It works best. It stops the function when the condition is met.
function anything() {
var get = document.getElementsByClassName("text ").value;
if (get == null) {
alert("Please put in your name");
}
return;
var random = Math.floor(Math.random() * 100) + 1;
console.log(random);
}
if (OK === guestList[3]) {
alert("Welcome");
script.stop;
}

Categories

Resources