简体   繁体   English

柯里化 function 和 javascript?

[英]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 ),但修改内部summervalueOf()最后返回的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM