How to change a variable to something if it's undefined? - javascript

I don't have my script completed yet or anything so I can't post the code. Basically I need a variable to change and keep going through a function increasing by one until it reaches its destination. Something like:
function one(a) {
var x = a;
var max = 3;
if (a < 3) {
// some code
two(x);
} else {
// function will end here quitting the whole thing and possibly other code
}
}
function two(x) {
var change = x+1;
one(change);
}
It all works how I need it but when I first enter function one how would I make it so when x = a doesn't have a value that it will by default be 0?
something like...
function one(a) {
var x = a;
var max = 3;
if (x = undefined) {
x = 0;
} else {
if (x < 3) {
// some code
two(x);
} else {
// function will end here quitting the whole thing and possibly other code
}
}
}
function two(x) {
var change = x+1;
one(change);
}
Any ideas?

You could do this:
function one(a) {
var x = a || 0;
if (x < 3) {
//debugger;
two(x);
} else {
// function will end here quitting the whole thing and possibly other code
alert('Done');
}
}
function two(x) {
x++;
one(x);
}
one();
FIDDLE
var x = a || 0 means x is a if a can be asserted as true or 0.
x++ means x = x + 1

You can check to see if the variable is defined and send it in the functions argument by using the short hand conditional.
typeof(a)=="undefined" ? 0 : a;
You can change your code to:
function one(a) {
var x = (typeof(a)=="undefined" ? 0 : a);
var max = 3;
if (x < 3) {
// some code
two(x);
} else {
// function will end here quitting the whole thing and possibly other code
return;
}
}
Fiddle: http://jsfiddle.net/gBBL2/

var x = (typeof a === 'undefined') ? 0 : a;
If a is undefined, use 0. Otherwise use a as the value of x.

Related

Restricting the scope of an assignment in conditional in JavaScript

The following code pushes all the points below the limit into data, until getPoint returns null.
while ((x = getPoint()) && x < limit) {
data.push(x)
}
console.log(x, 'x should be undefined here')
In this particular case I use an assignment in a conditional, I know it looks ugly, but the question focuses on x which is not local to the block. I tried to place a let there, but it doesn't work.
Is it possible to restrict the scope of x inside the while statement?
Another working implementation would be this one, but in this case I double the test on x:
do {
let x = getPoint()
if (x && x < limit) {
data.push(x)
}
} while(x && x < limit)
or
while (true) {
let x = getPoint()
if (!x || x >= limit) {
break;
}
data.push(x)
}
or
function* getPointIterator(limit) {
let x = getPoint()
while(x && x < limit) {
yield x;
}
}
data.push(...getPointIterator(limit))
You may consider to change the while loop with a for loop:
var limit = 3;
var r = 2;
var data = [];
function getPoint() {
return r++;
}
for (let x=0; (x = getPoint()) && x < limit;) {
data.push(x)
}
console.log(typeof(x) === 'undefined' ? 'undefined' : x, 'x should be undefined here')
1. Code block {...}
You can use a “bare” code block {…} to isolate variables into a “local scope”.
{
// do some job with local variables that should not be seen outside
let message = "Hello";
alert(message); // Hello
}
alert(message); // Error: message is not defined
For your case:
const limit = 3;
let y = 0;
const getPoint = () => y++;
{
let x = 0;
while ((x = getPoint()) && x < limit) {
console.log(x);
}
}
console.log(x, 'x should be undefined here');
The code outside of the block (or inside another script) doesn’t see variables inside the block, because the block has its own Lexical Environment.
2. IIFE (function {...})
You can use so-called “immediately-invoked function expressions” (abbreviated as IIFE) used for this purpose.
They look like this:
(function() {
let message = "Hello";
alert(message); // Hello
})();
For your case:
const limit = 3;
let y = 0;
const getPoint = () => y++;
(function () {
let x = 0;
while ((x = getPoint()) && x < limit) {
console.log(x);
}
})();
console.log(x, 'x should be undefined here');
Here a Function Expression is created and immediately called. So the code executes right away and has its own private variables.
The Function Expression is wrapped with brackets (function {...}), because when JavaScript meets "function" in the main code flow, it understands it as the start of a Function Declaration.

I cannot return the real variable on processed recursion?

I have been doing this recursion in javascript; however I cannot return the real value of x on return. Instead, it is returning the processed value. The code is doing it's job but it's returning the processed variable on recursion. I tried to store the variable on x, but I still fail.
I want to return the last call stack to get the real variable.
This code returns 0 is Even, 1 is Even - how can the code be changed such that these cases would work as expected?
function isEven(x) {
var y =x;
if (x<0) {
x = x * -1;
}
if ( x===0 ) {
return console.log(y+' is Even');
} else if( x===1 ) {
return console.log(y+' is Odd');
} else {
return isEven(x-2);
}
// →
console.log(isEven(10));
console.log(isEven(-11));
}
You cannot access the initial value using your code.
The simplest way to achieve this goal is to add a function parameter, which will store the original value:
function isEven(x, initial) {
initial = initial || x; // so that isEven(10) => isEven(10, 10)
if (x<0) {
x = x * -1;
}
if(x===0) {
return initial+' is Even';
} else if(x===1) {
return initial+' is Odd';
} else
return isEven(x-2, initial);
}
// →
console.log(isEven(10));
console.log(isEven(-11));
However, the correct solution is to separate the initial call and recursive calls. For example, it can be achieved using nested functions.
It is also a good idea to abstract logics (boolean) and displayed information (string).
function isEvenString(initial) {
function isEvenBool(x) {
if (x < 0) {
x = x * -1;
}
if (x === 0) {
return true;
}
if (x === 1) {
return false;
}
return isEvenBool(x - 2);
}
return initial + (isEvenBool(initial) ? " is Even" : " is Odd");
}
// →
console.log(isEvenString(10));
console.log(isEvenString(-11));
P.S. Note that this isEven function is good for education purposes, but absolutely useless in practice. It takes 1 000 000 function calls to determine that 2 000 000 is even whilst it can be done using one line of code in O(1) operations:
function isEvenString(x) {
return x % 2 === 0;
}
I assume what you're trying to do is print the original value that was given, not the final value from the recursion. But you're reassigning y every time you recurse, so it doesn't contain the original value.
One solution is to split the function up into a main function and a recursive internal function.
function isEven(x) {
var y =x;
function isEvenRecurse(x) {
if (x<0) {
x = x * -1;
}
if(x===0) {
return y+' is Even';
} else if(x===1) {
return y+' is Odd';
} else {
return isEvenRecurse(x-2);
}
}
isEvenRecurse(y);
}
Another way is to pass an extra argument to the function when recursing.
function isEven(x, y) {
if (arguments.length == 1) {
y = x;
}
if (x<0) {
x = x * -1;
}
if(x===0) {
return y+' is Even';
} else if(x===1) {
return y+' is Odd';
} else {
return isEven(x-2, y);
}
}

Recursive function or loop in javascript?

I am trying to write a recursive function, but I am completely lost as to how to implement it. I currently have the following:
function change(p){
// code for function
}
var c1 = change(start);
var c2 = change(c1);
var c3 = change(c2);
// etc. etc.
Is there any way to do this with a while loop? For example:
while(currentResultofFunction != goal)
nestedly loop through as before until reaches true
function change(p) {
if (p != 1) { // your condition
change(p);
} else return p;
}
What about:
var val = start;
while(val) //or while val != goal
val = change(val);
What you are doing, is not recursive. You maybe mean iterative.
You can loop through the variables in this way:
var n = 2;
for (var i = 1; i <= n; i++) {
if (i == 1) window['c1'] = change(start);
else window['c' + i] = change(window['c' + (i - 1)]);
}

Change the parameter like this [function.value(new-value)]

function add(n) {
return function(x) {
this.value = n;
return this.value + x;
}
}
var add3 = add(3);
var add4 = add(4);
I'm trying to figure out if I can re-write this function above to:
Allow to modify the first parameter like this:
add3.value(1);
console.log(add3(4))
// 5
Also so that the value method returns the current value if no parameter is passed:
add3.value(1);
console.log(add3.value())
// 1
Functions are just objects, so you can assign a property value to it, whose value is a function that modifies n:
function add(n) {
var result = function(x) {
return n + x;
};
result.value = function(x) {
if (typeof x === 'undefined') {
return n;
}
n = x;
};
return result;
}
Why you'd want to do that I don't know, but it's possible.
To use the interface you've described, your inner function will need to return a object with a 'value' method.
eg.
function add (n) {
return {
value: function (x) {
x = x || 0;
return n + x;
}
};
}
But, what it sounds like you're trying to do is currying & partial application. In which case, returning a function is probably simpler.
function add (n) {
return function (x) {
x = x || 0;
return n + x;
};
}
This would be used like so:
var add3 = add(3);
console.log(add3(4)); // output: 7
or, with the default value:
var add4 = add(4);
console.log(add4()); // output: 4
Similar to Felix's answer, but permitting empty inputs, remembering last values and also giving it a valueOf so it can be used like a number itself.
function adder(i) {
i || (i = 0);
var add = function (x) {
return i += (+x || 0); // += modifies i
};
add.value = function (x) {
return !x && x !== 0 ? i : i = (+x || 0); // if x falsy but not zero
};
add.valueOf = function () {
return i;
};
return add;
}
var add = adder();
add.value(1); // 1
add(4); // 5
add(5); // 10
add + 2; // 12, via valueOf
add(); // 10

Max call stack exceeded

I understand what maximum call stack exceeded is. However, is there a workaround for this for my code? Furthermore, there will be a time where it eventually will stop looping, that is when position > counter1.
var a = 0;
var b = 1;
var c;
var counter1 = 1;
var position = 0;
window.onload = function() {
var position = prompt("Please enter the position number.","0");
calc1();
}
function calc1() {
if(position <= counter1) {
c = a+b;
counter1++;
calc2();
}
else {
callResult();
}
}
function calc2() {
if(position <= counter1) {
a = b+c;
counter1++;
calc3();
}
else {
callResult();
}
}
function calc3() {
if(position <= counter1) {
b = c+a;
counter1++;
calc1();
}
else {
callResult();
}
}
function callResult() {
if (position %3 == 1) {
document.getElementById("answer").innerHTML = a;
}
else if (position %3 == 2) {
document.getElementById("answer").innerHTML = b;
}
else {
document.getElementById("answer").innerHTML = c;
}
}
You should avoid recursion and use loop. Something like this:
window.onload = function() {
var position = prompt("Please enter the position number.","0");
maincalc();
}
function maincalc() {
var subcalc = [ calc1, calc2, calc3 ];
var calccount = 0;
while(position <= counter1) {
subcalc[ calccounter ]();
calccounter = (calccounter +1) % 3;
}
}
The value of position is given once and never changed.
You then check, if(position <= counter1) in each call calc1, calc2, calc3 which call each other thus:
calc1 -> calc2 -> calc3 -> calc1 -> ...
This will clearly continue until you run out of stack space.
Perhaps if you increment position instead of counter1 or keep calling while position is greater than the counter this problem will go away,
i.e.
if(position > counter1)
You probably need to step back and think about what you are really trying to do.
as I understand you are calculating Fibonacci numbers sum?
see this Javascript Fibonacci answer to learn how to do it much easier and without any recursive calls

Categories

Resources