Reputation: 45
Question as below:
create a sum function, and the requirement:
sum(1,2).result === 3
sum(1,2)(3).result == 6
sum(1,2)(3,4).result == 10
sum(1,2)(3,4)(5).result == 15
This is a question about currying in JS. I have implemented the most functions of the question. The tricky point is .result for me.
What does .result means after sum(1,2)? Is it an attribute?
How to add the .result to my code?
function sum(){
var count = 0;
for(let i=0; i<arguments.length; i++){
count += arguments[i];
}
var tmp = function(){
for(let i=0; i<arguments.length; i++){
count += arguments[i];
}
return tmp;
}
tmp.toString = function(){
return count;
}
return tmp;
}
console.log(sum(1,2))
console.log(sum(1,2)(3))
Upvotes: 0
Views: 1093
Reputation: 14904
Here a solution. It always better to use spread operator on the arguments instead of using arguments
keyword. Witch should be avoided
function sum(...args){
let count = 0;
count += args.reduce((a,v) => a + v);
let res = sum.bind(this,count);
res.result = count;
return res;
}
console.log(sum(1,5)(4)(5).result)
Upvotes: 0
Reputation: 638
Currying is an advanced technique of working with functions. It’s used not only in JavaScript, but in other languages as well.
Currying is a transformation of functions that translates a function from callable as f(a, b, c)
into callable as f(a)(b)(c).
Currying doesn’t call a function. It just transforms it.
Let’s see an example first, to better understand what we’re talking about, and then practical applications.
We’ll create a helper function curry(f)
that performs currying for a two-argument f
. In other words, curry(f)
for two-argument f(a, b)
translates it into a function that runs as f(a)(b)
:
function curry(f) { // curry(f) does the currying transform
return function(a) {
return function(b) {
return f(a, b);
};
};
}
// usage
function sum(a, b) {
return a + b;
}
let curriedSum = curry(sum);
alert( curriedSum(1)(2) ); // 3
Also Refer this link for more details
Upvotes: 0
Reputation: 192
Shrey answer is Perfect but we can make it more sorter and clear.
function sum() {
let result = [...arguments].reduce((acc, num) => acc + num, 0);
let newSum = sum.bind(this, result);
newSum.result = result;
return newSum;
}
console.log(sum(3,4)(5)(9).result);
console.log(sum(3,4)(5,6)(9).result);
Upvotes: 0
Reputation: 392
You can add .result to your code by storing result as a property in function.
You can also remove the redundant tmp
function code .
Here is how it looks:
function sum(){
var count = 0; // use previous result
for(let i=0; i<arguments.length; i++){
count += arguments[i];
}
const newSum = sum.bind(this,count);
newSum.result = count;
return newSum;
}
console.log(sum(1,2).result)
console.log(sum(1,2)(3).result)
.bind()
here binds the first argument of cloned function (newSum) as count , which will be used on all subsequent calls
Upvotes: 3