Variadic curried sum function

前端 未结 16 1848
清酒与你
清酒与你 2020-11-22 06:33

I need a js sum function to work like this:

sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10 
etc.

I heard it can\'t be done. But heard

相关标签:
16条回答
  • 2020-11-22 07:23
    let add = (a) => {
      let sum = a;
      funct = function(b) {
        sum += b;
        return funct;
      };
    
      Object.defineProperty(funct, 'valueOf', {
        value: function() {
          return sum;
        }
      });
      return funct;
    };
    
    
    console.log(+add(1)(2)(3))
    
    0 讨论(0)
  • 2020-11-22 07:24

    Here's a solution with a generic variadic curry function in ES6 Javascript, with the caveat that a final () is needed to invoke the arguments:

    const curry = (f) =>
       (...args) => args.length? curry(f.bind(0, ...args)): f();
    
    const sum = (...values) => values.reduce((total, current) => total + current, 0)
    curry(sum)(2)(2)(1)() == 5 // true
    

    Here's another one that doesn't need (), using valueOf as in @rafael's answer. I feel like using valueOf in this way (or perhaps at all) is very confusing to people reading your code, but each to their own.

    The toString in that answer is unnecessary. Internally, when javascript performs a type coersion it always calls valueOf() before calling toString().

    
    // invokes a function if it is used as a value
    const autoInvoke = (f) => Object.assign(f, { valueOf: f } );
    
    const curry = autoInvoke((f) =>
       (...args) => args.length? autoInvoke(curry(f.bind(0, ...args))): f());
    
    
    const sum = (...values) => values.reduce((total, current) => total + current, 0)
    curry(sum)(2)(2)(1) + 0 == 5 // true
    
    0 讨论(0)
  • 2020-11-22 07:25

    You can make use of the below function

    function add(num){
       add.sum || (add.sum = 0) // make sure add.sum exists if not assign it to 0
       add.sum += num; // increment it
       return add.toString = add.valueOf = function(){ 
          var rtn = add.sum; // we save the value
          return add.sum = 0, rtn // return it before we reset add.sum to 0
       }, add; // return the function
    }
    

    Since functions are objects, we can add properties to it, which we are resetting when it's been accessed.

    0 讨论(0)
  • 2020-11-22 07:26

    I'm posting this revision as its own post since I apparently don't have enough reputation yet to just leave it as a comment. This is a revision of @Rafael 's excellent solution.

    function sum (n) {
        var v = x => sum (n + x);
        v.valueOf = () => n; 
        return v;
    }
    
    console.log(+sum(1)(2)(3)(4)); //10
    

    I didn't see a reason to keep the v.toString bit, as it didn't seem necessary. If I erred in doing so, please let me know in the comments why v.toString is required (it passed my tests fine without it). Converted the rest of the anonymous functions to arrow functions for ease of reading.

    0 讨论(0)
  • 2020-11-22 07:26

    Might be an old question but a little extended answer

    function sum() {
    
        var args = [];
        args.push(...arguments);
    
        function sumOfAllArguments() {
            return args.reduce((prev,items)=>prev + items, 0)
        }
    
        function v() {
            arguments && args.push(...arguments);
            return arguments.length === 0 ? sumOfAllArguments() : v;
        }
    
        v.valueOf = v.toString = sumOfAllArguments;
    
        return v;
    
    }
            
        
    
            console.log(sum(2)(2)(2)()) // 6
            console.log(sum(2)(2)(2).toString()) // 6
            console.log(sum(2)(2)(2).valueOf()) // 6
            console.log(+sum(2)(2)(2)) //6
            console.log(sum(2)(2)(2)) // f 6
    
            console.log(sum(2,2,2)(2,2)(2)) // f 12
            console.log(sum(2)(2,2)(2)()) //  8

    0 讨论(0)
  • 2020-11-22 07:26
       function sum(a){
        let res = 0;
        function getarrSum(arr){
                return arr.reduce( (e, sum=0) =>  { sum += e ; return sum ;} )
         }
    
        function calculateSumPerArgument(arguments){
                let res = 0;
                if(arguments.length >0){
    
                for ( let i = 0 ; i < arguments.length ; i++){
                    if(Array.isArray(arguments[i])){
                        res += getarrSum( arguments[i]);
                    }
                    else{
                      res += arguments[i];
                    }
                 }
              }
                return res;
         }
        res += calculateSumPerArgument(arguments);
    
    
    
        return function f(b){
            if(b == undefined){
                return res;
            }
            else{
                res += calculateSumPerArgument(arguments);
                return f;
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题