[英]Currying function sum javascript?
How can I create a function in javascript return like this:如何在 javascript 中创建 function 返回,如下所示:
sum(1,2) //3
sum(1,3)(2) // 6
I have tried with this code but it wrong?我已经尝试过使用此代码,但它错了吗?
function(a,b) {
return (c) {
return a + b + c;
}
}
You could override the valueOf
of the inner function and sum the arguments ( reference )您可以覆盖内部 function 的valueOf
并对 arguments 求和(参考)
function sum(...a) { function inner(...b) { a.push(...b) return inner; } inner.valueOf = () => a.reduce((c, d) => c + d, 0) return inner } console.log( +sum(1, 2) ) console.log( +sum(1, 3)(2) ) console.log( +sum(1, 2, 3)(4, 5)(6) )
You could use rest syntax to collect all the parameters and return a function.您可以使用 rest 语法来收集所有参数并返回 function。 This needs another ()
at the end to terminate the recursion这需要最后一个()
来终止递归
const sum = (...a) => (...b) => b.length
? sum(...a, ...b)
: a.reduce((c, d) => c + d, 0)
const sum = (...a) => (...b) => b.length? sum(...a, ...b): a.reduce((c, d) => c + d, 0) console.log( sum(1,2)() ) console.log( sum(1,3)(2)() ) console.log( sum(1,2,3)(4,5)(6)() )
Since you are not going for fixed length arguments, I can only think of using a hack like below where we finally still return a function ( summer
) but modify the valueOf()
for the inner function summer
so that in the end when we do an operation like *1
on the last returned function which will be summer
only, summer.valueOf()
get's invoked and we can see the total sum till now.由于您不打算使用固定长度的 arguments,我只能想到使用如下所示的 hack,我们最终仍然返回 function( summer
),但修改内部summer
的valueOf()
最后返回的 function 上的*1
之类的操作仅适用于summer
,调用了summer.valueOf()
,我们可以看到到目前为止的总和。
function sum(...args){ function summer (...args2){ let argsArr = [...args,...args2]; return sum(...argsArr) } summer.valueOf=()=>args.reduce((acc,curr)=>acc+=curr,0); return summer; } console.log(sum(1,2)*1); console.log(sum(1,2)(3)*1); console.log(sum(1,2)(3)(4,5,6,7,8)(9,10,11)*1);
The result of a function cannot vary based on whether it is called again or not. function 的结果不能根据是否再次调用而有所不同。 So, it is not possible to have sum(1, 2)
that returns a number in one case but a function if called as sum(1, 2)(3)
.因此,不可能有sum(1, 2)
在一种情况下返回一个数字,而是 function 如果被称为sum(1, 2)(3)
。
However, since functions are objects in JavaScript, you can have the function return a new function with a property that has the total:但是,由于函数是 JavaScript 中的对象,因此您可以让 function 返回一个新的 function ,其属性为:
const sum = (function calculate() { return function running(...xs) { const total = xs.reduce((sum, x) => sum + x, running.total?? 0); return Object.assign( calculate(), { total } ) } })(); console.log( sum(1, 2).total ); console.log( sum(1, 3)(2).total ); console.log( sum(1, 2, 3)(4, 5)(6).total ); console.log( sum(1, 2, 3, 4, 5, 6).total ); console.log( sum(1)(2)(3)(4)(5)(6).total ); const x = sum(1, 2); console.log( x(3).total ); console.log( x(3).total );
This uses a self-referencing IIFE to keep things clean, as there is no need for an extra function.这使用自引用 IIFE 来保持清洁,因为不需要额外的 function。 However, it is otherwise equivalent to:但是,它在其他方面等价于:
function calculate() {
return function running(...xs) {
const total = xs.reduce((sum, x) => sum + x, running.total ?? 0);
return Object.assign( calculate(), { total } )
}
}
const sum = calculate();
The calculate()
function always returns a new running()
function that keeps track of the total and itself returns a new running()
function with the total
attribute. calculate()
function 总是返回一个新running()
function 来跟踪总数,它本身返回一个新running()
function 和total
属性。 When running()
calculates the sum, it uses the total
it has or a zero if no total
was present (first time calculate
was executed).当running()
计算总和时,它使用它的total
,如果不存在total
,则使用零(第一次执行calculate
)。
sum(1, 2, 3) (4, 5) (6) .total --> 21
^^^^^^^^^^^^ ^^^^^^ ^^^
| | |
total = 6 <--+ | |
total = 6 + 9 <-----+ |
total = 15 + 6 <---------+
If you prefer, you can also make sure that the function is convertible to a primitive number by overriding the valueOf
and @@toPrimitive
methods.如果您愿意,还可以通过覆盖valueOf
和@@toPrimitive
方法来确保 function 可转换为原始数字。 Technically, you do not need both but does not hurt to be more thorough:从技术上讲,您不需要两者都需要,但更彻底也无妨:
const sum = (function calculate() {
return function running(...xs) {
const total = xs.reduce((sum, x) => sum + x, running.total ?? 0);
return Object.assign( calculate(), {
total,
valueOf: () => total,
[Symbol.toPrimitive]: () => total,
})
}
})();
const sum = (function calculate() { return function running(...xs) { const total = xs.reduce((sum, x) => sum + x, running.total?? 0); return Object.assign( calculate(), { total, valueOf: () => total, [Symbol.toPrimitive]: () => total, }) } })(); console.log( +sum(1, 2) ); console.log( +sum(1, 3)(2) ); console.log( +sum(1, 2, 3)(4, 5)(6) ); console.log( +sum(1, 2, 3, 4, 5, 6) ); console.log( +sum(1)(2)(3)(4)(5)(6) ); const x = sum(1, 2); console.log( +x(3) ); console.log( +x(3) ); console.log( sum(1, 2) + sum(3) + sum(4)(5) );
Follow the below code:-请按照以下代码:-
function currying(first, ...other){ var argmnts = [first, ...other]; return function interalCurrying(first, ...other) { if(first){ argmnts = [...argmnts, first, ...other]; return interalCurrying; } else { return argmnts.reduce((acc, val)=>{ return acc+val; },0); } } } console.log(currying(2,3)(4)()); console.log(currying(2)(3)(4)());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.