最近我在hackerrank面临一个问题,即必须计算乘法运算并且必须返回答案。例如
function multiply(a,b) {
return a*b;
}
现在这里是函数可能以不同方式调用的问题,例如
multiply(4,5);
multiply(4)(5);
multiply(4)(5)(6);
我知道我们必须为第二个关闭apporach,即乘法(4)(5)。我已为此编写代码
function multiply(a,b) {
return function(b) {
return a*b;
}
}
现在如果已经使用3个参数乘以(4)(5)(6)调用了它的乘法函数。如何识别函数的调用方式以及如何为所有输入编写通用解决方案。
感谢任何帮助。谢谢
答案 0 :(得分:3)
要拥有无限的callchain,你需要一些js技巧:
function multiply(...args){
//make the chain endless through using some recursive like stuff:
const func = (...args2) => multiply(...args,...args2);
//the chains endpoint:
func.valueOf = function(){
return args.reduce((a,b) => a*b);
};
return func;
}
这种变量currying的问题在于它的无限,所以theres(通常)无法结束它。
multiply(1) // func :/
然而在javascript中它可以为函数分配方法,所以我们可以很容易地调用方法而不是函数来结束链:
multiply(1)(2)(3).valueOf()
所以你可以这样做:
console.log(
+multiply(1,2,3)(4)(5),
+multiply(1,2)
);
+等于 valueOf ,因此需要结束链,但是对 valueOf 的调用是由javascript中的许多操作推断的(所有数学运算如 - * /).
答案 1 :(得分:1)
这种方法的问题在于返回值的模糊性。它必须同时是Number
和function
。
由于valueOf()
方法可以模拟该行为,但我很少建议在生产中使用它。
const wrap = (accumulator, value) => {
let fn = (...args) => args.length? wrap(accumulator, args.reduce(accumulator, value)): fn;
fn.valueOf = () => value;
return fn;
}
let mul = wrap((a,b) => a*b, 1);
console.log(+mul(4,5));
console.log(+mul(4,5)(6));
console.log(mul(4,5) * 6);
console.log(+mul(4)(5,6)(7)(8,9)()(10));
//or maybe a different operation?
let add = wrap((a,b) => a+b, 0);
console.log(+add(1,2,3,4,5));

.as-console-wrapper{top:0;max-height:100%!important;}

这种方法的缺点是,它变得如此灵活(和暧昧),它几乎没用,因为它太难以理解你在使用时会得到什么结果这是内联的。如果你将某些功能用于做一个类型测试怎么办?那你就麻烦了。
答案 2 :(得分:0)
你关闭了,你要做的事情被称为currying,这是一种利用闭包的技术。
在这种情况下,您的函数一次只能使用一个参数:
function multiply(a) {
return function(b) {
return a * b;
}
}
现在你可以说
function multiplyBy5 = multiply(5);
console.log(multiplyBy5(4)); //would log 20
如果你只想要最多3个参数,你可以这样做:
function multiply(a) {
return function(b) {
return function(c) {
c = c || 1;
return a * b * c;
}
}
}
这使得c成为可选参数。您可以通过
调用该功能multiply(4)(5)()
//or
multiply(4)(5)(6)