How can I get this javascript function to call itself? - javascript

As of right now my sum function looks like the code below. It works and returns the sum of the consecutive calls. But how can I make this work without the empty parenthesis at the end? Like so theSum(5)(4)(3) which returns 12.
function theSum(x) {
var total = x;
function rec(y) {
if (y === undefined) return total;
total += y;
return rec;
};
return rec;
}
console.log(theSum(5)(4)(3)()); // 12

Here is a suggestion utilizing a toString method:
function theSum(x) {
var total = x;
function rec(y) {
total += y;
return rec;
};
rec.toString = function() { return total; }
return rec;
}
alert(theSum(5)(4)(3));
console.log(parseInt(theSum(5)(4)(3)));
Note however that you need to convert the returned reference to a string in some way so that you see the result.

This is not possible. A function cannot return a function and an integer. You can make theSum(5, 4, 3) = 12 or theSum([5, 4, 3]) = 12.

Closures and JavaScript duck typing to the rescue:
function NumSumFun(initial){
function NumSumNext(num) {
initial+= num;
return NumSumNext;
}
NumSumNext.valueOf = function () { return initial; }
return NumSumNext;
}
var x = NumSumFun(10)(29); // ==> function 39
x + 1; // ==> 40
So whats happening. It returns a function but the function has a valueOf property that has access to the accumulated value so the function acts as a number when used as a number.

Related

Add values on subsequent call in javascript function.?

Let's consider I have the following function call,
function add(){
x = 0 ;
for(i = 0 i < ##; i++){ // need to run a loop four times
x+=1
}
}
Let's consider I am trying to Implement the function that will add one on each subsequent call, like below
console.log(add()()().getValue()); // 3
console.log(add().getValue()); // 1
console.log(add()().getValue()); // 2
A call to add must return a function which also has a getValue method, and each call to that function must return the same thing. So:
function add() {
var x = 1;
function inner() {
x += 1;
return inner;
}
inner.getValue = function () {
return x;
}
return inner;
}
console.log(add()()().getValue()); // 3
console.log(add().getValue()); // 1
console.log(add()().getValue()); // 2
My guess is they were expecting you to use toString() which is not the greatest way of doing this.
function add(x = 0) {
function next() {
return add(x+1);
}
next.toString = function () {
return x;
};
return next;
}
console.log("example 1", add()()()());
console.log("example 2", add()()()()()()()()());
I think you are trying to emulate the behavior of generator functions. Here is a snippet that illustrates one way you could do it with a generator.
function* adder() {
let x = 0;
while (true) {
yield x + 1;
x++;
}
}
const add = adder();
const firstValue = add.next();
const secondValue = add.next();
const thirdValue = add.next().value;

factorial function returns undefined

This a simple code for factorial, I have written the function and it loops through giving right output but at the end, it returns undefined. I don't know why.
function factorial(n){
let value=1;
for(let i=1;i<=n;i++) {
value = i*value;
console.log(value);
}
}
Because you do not return anything from the function, so undefined is the result of its work.
You need to return the value explicitly:
function factorial(n){
let value=1;
for(let i=1;i<=n;i++) {
value = i*value;
console.log(value);
}
return value;
}
You can find factorial by using recursion. Here is the implementation.
function factorial(x){
if(x == 0) //Exit condition
return 1;
return x * factorial(x-1); //5*4*3*2*1
}
console.log(factorial(5));
This is good implementation:
const factorial = n => n > 1 ? n * factorial(--n) : 1;
And your function does not have return, so it returns undefined;

Javascript - how to detect how many functions are being called? (multiple parentheses)

Let me propose an example that works, then follow up with what fails, highlighting the point to my question.
Here, we have 3 functions being called (1 named, 2 anonymous):
var add = function(a, b) {return a+b};
var multiply = function(a, b) {return a*b};
function myFunction(fxn) {
return function(x) {
return function(y) {
return fxn(x,y);
}
}
}
myFunction(add)(2)(3)
Understandably, this call fails:
myFunction(add)(2)(3)(4)
How would I detect how many functions are being called? In the 2nd call, I'm calling 4 functions (1 named, 3 anonymous).
How would I rewrite the myFunction function in a way that compensated for any given amount of calls? I know we can detect how many arguments a function was given, but is there a way to detect how many functions are being called? I hope I worded this correctly. Thanks.
To find out if a variable contains a reference to a function you can use below code:
if (typeof(v) === "function") alert("This is a function")
Based on above you can find out on how many nested functions there are
function myFunction() {
return function() {
return function() {
return 1 + 2;
}
}
}
var count = 0;
var v = myFunction();
while (typeof(v) === "function") {
count++;
v = v();
}
alert("Nr of nested functions: " + count)
Even if this has no practical use case I can think of, this is a possible solution:
var add = function(a, b) {
return a + b
};
var multiply = function(a, b) {
return a * b
};
var counter = 0;
var result = 0;
function myFunction(fxn) {
counter = 1;
result = 0;
return function first(x) {
++counter;
return function second(y) {
++counter;
x = result ? result : x;
result = fxn(x, y);
return second;
}
}
}
myFunction(add)(1)(2)(3)(4);
alert('Result is: ' + result + '; Parentheses count: ' + counter);

Reverse order of an array and return the size of it javascript

I have a strange problem. I have to implement a function count(s) which inverts the getNumberSequence function that I have already create. (i.e: count(getNumberSequence(x)) == x, for all integers x > 0). I have my function and I have also the logic to resolve the problem but I don't know how to do it. In my case I want to call the previous string of ordered numbers, split them and call the last number. The problem is, how can I call the return of another method? Here are my codes:
function getNumberSequence(number) {
var result = "";
if (number <= 0) {
return result;
} else {
var first = true;
for (i = 1; i <= number; i++) {
if (first) {
first = false;
} else {
result += ", ";
}
result += i;
}
}
return result
}
Basically I need the variable result in this case to call it in the other function.
function count(s) {
var d = s. split(', ');
return d[-1];
}
I know that the second code is wrong but I don't know how to fix it. I have implemented a test that is:
test( "Count", function() {
for (i = 1; i<10000; i = i + 10) {
equal(count(getNumberSequence(i)) , i, "count(getNumberSequence(" +i + ")) should return " + i);
}
I know that the answer could be stupid but I started javascript yesterday for the first time. Hope you can help me. Thanks to everyone
If I understand you correctly you want to pass a number, say 10, into the first function and have that return a string of numbers up to 10 and then for count to read that string and return 10 (as an integer) again? This will do the trick. It takes the string, splits it, and pops out the last number converting it to an integer before it returns it.
function count(seq) {
return parseInt(seq.split(', ').pop(), 10);
}
I could rewrite it like this:
function count(seq) {
// create an array
var arr = seq.split(', ');
// grab the last element (a string)
var lastElement = arr.pop();
// convert the string to an integer
var convertedInteger = parseInt(lastElement, 10);
// return the integer
return convertedInteger;
}
If you wanted to use reverse and grab the first element, do this:
function count(seq) {
return parseInt(seq.split(', ').reverse()[0], 10);
}
Or use shift which does the same thing:
function count(seq) {
return parseInt(seq.split(', ').reverse().shift(), 10);
}
DEMO

how can i implement this logic add(1)(2)(1).. upto (n)?

I know this question is already answered with limited capability but I want it with n number of time with n arguments?
function add(x) {
return function(y) {
if (typeof y !== 'undefined') {
x = x + y;
return arguments.callee;
} else {
return x;
}
};
}
add(1)(2)(3)(); //6
add(1)(1)(1)(1)(1)(1)(); //6
problem is this works only when I add extra empty brackets ()
it doesn't work if do this add(1)(2)(3)
reference question
Try this:
function add(x) {
var fn = function(y) {
x = x + y;
return arguments.callee;
};
fn.toString = function(){ return x; };
return fn;
}
The following code works exactly like you asked:
function add(a)
{
var c=a,b=function(d){c+=d;return arguments.callee;};
b.toString=function(){return c;}return b;
}
Do note that some operations will detect the result given as a function, but any functions that require a string or integer will see the proper value.
Try sending your numbers as an array and changing your function code to reflect these changes.
Note: Code untested.
function add(x) {
var result = 0;
for (i = 0; i < x.length;i++){
result+=x[i];
}
return result;
}
add(new Array(1,2,3));

Categories