4

How to implement a locking function for multiplying an arbitrary number of numbers.

Example of a call:

multiply(1)(2)(3)(4)(5) // 120

To accomplish this task, it is necessary to redefine the toString method for the internal function, which should return the accumulated result, but I had result NaN.

function Multiply(arguments) {
  for (var i = 0; i < arguments.length; i++) {
    var number = arguments.length[i];
  }
  return function(res) {
    return number * res.valueOf();
  };
}
console.log(Multiply(5)(5)(6)(8));
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Igor Shvets
  • 547
  • 6
  • 15
  • 3
    `arguments.length[i]` doesn't make sense since `length` returns an integer. Read up on how to create a "curried" function or the term "currying" – charlietfl May 06 '18 at 16:40
  • Indeed. You only have one argument to `Multiply`. – Amadan May 06 '18 at 16:41
  • 1
    https://stackoverflow.com/questions/33901793/writing-a-curried-javascript-function-that-can-be-called-an-arbitrary-number-of https://stackoverflow.com/questions/46286531/how-to-write-a-sum-function-with-infinite-number-of-arguments-using-currying-in https://stackoverflow.com/questions/48576573/how-can-i-construct-a-infinite-fun-in-javascript?noredirect=1&lq=1 https://stackoverflow.com/questions/35039020/currying-a-function-that-takes-infinite-arguments – VLAZ May 06 '18 at 16:45
  • Possible duplicate of [Is it possible to write continuous nested functions in JavaScript?](https://stackoverflow.com/questions/48889069/is-it-possible-to-write-continuous-nested-functions-in-javascript) – Redu May 06 '18 at 16:55

3 Answers3

5

First of all do not use arguments as parameter in a function, because this variable is available in functions as array like object for the arguments of the function (arguments object).

Then you need to have an inner function m which uses the arguments and calculates the product and returns the function itself.

The inner function gets a toString method for getting the final result.

At last you need to call the inner function with all arguments of the outer function.

A small hint, take only a lower case letter for not instanciable function.

function multiply(...args) {
    function m(f, ...a) {
        p *= f;
        if (a.length) {
            m(...a);
        }
        return m;
    }

    var p = 1;            // neutral value for multiplication
    m.toString = _ => p;
    return m(...args);
}

console.log(multiply(5)(5)(6)(8));
console.log(multiply(2, 3, 4)(5)(6, 7));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • It is not work. It returns: [Function: m] { toString: [Function (anonymous)] } – north.inhale Dec 16 '22 at 12:14
  • @north.inhale, actually this works only here at stackoverflow. to get a fullworking result, you could have a look to [this](https://stackoverflow.com/questions/74625818/how-to-make-a-function-add-which-works-in-javascript-console-logadd234/74625984#74625984) answer. – Nina Scholz Dec 16 '22 at 12:23
4
  1. The function returned by Multiply should return itself after each call.
  2. valueOf should be assigned to that function not to its argument which will be a number.
  3. Multiply should call the inner function with its argument (the initial number).
  4. No need to use the arguments object as there will always be one argument.

function Multiply(initialNum) {
    var product = 1;

    function fn(num) {
        product *= num;
        return fn;
    };

    fn.valueOf = function() { return product; };

    return fn(initialNum);
}

console.log(0 + Multiply(5)(5)(6)(8));

Note: The 0 + in console.log is to assure that valueOf will be called as the SO snippett console doesn't seem to work properly.

ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
1

You can implement it by overwriting Function#toString method which would call internally in major caser(for eg: while using with alert() function, string concatenation, etc...).

function Multiply(arg) {
  // calcumate the multiplication result
  var res = (this.value || 1) * arg,
    // bind this argument as an object which contains previous result
    returnFn = Multiply.bind({
      value: res
    })

  // overwrite toString method to return the current result
  returnFn.toString = function() {
    return res;
  }

  // return the function 
  return returnFn;
}


console.log(Multiply(5)(5)(6)(8));
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188