我们大多数人都知道我们可以创建一个这样的简单函数。
function calc(a,b){
return a+b
}
calc(1,1); //returns 2
我们也可以做这样的事情
function calc(a){
return function(b){
return a+b
}
}
calc(1)(1); //returns 2
如果我们有多个参数呢?
function calc() {
function r(arg) {
var a = [];
for(var i = 0, l = arg.length; i < l; i++){
a[i] = arg[i];
}
return a.reduce(function(p, c) {
return p + c;
});
}
var res = r(arguments);
return function() {
res += r(arguments);
return res;
}
}
适用于calc(1,2)(1)
,但不适用于calc(1,2,1)
有没有办法合并两个版本?
这意味着在打电话时
calc(1,1)
我们也可以致电calc(1)(1)
,两者仍然会返回2.
或calc(1,2,3)
calc(1,2)(3)
calc(1)(2,3)
全部返回6
答案 0 :(得分:1)
之后需要知道要进行计算的参数数量; - )
你可以创建一个将事物转化为这种功能的函数 像这样的东西:
function curry(f){
var args = [];
return addargs;
function addargs(){
args=args.concat([].slice.call(arguments));
return args.length<f.length? addargs.bind(this) : f.apply(this,args);
}
}
然后你可以这样做:
var calc = curry(function(a,b,c){return a+b+c});
calc(1,2)(3); // = 6
但你不能让它采用可变数量的参数和来讨论那些 - 它不知道何时返回答案
答案 1 :(得分:1)
所以这是我最接近我的问题。
使用下面的代码,如果我在函数前面添加一个+号,它就可以工作
所以+calc(1,2,3)
+calc(1,2)(3)
+calc(1)(2)(3)
+calc(1,2)(1)(3,0,1)
将全部运作
function calc(){
var args = [].map.call(arguments, function(a) {
return a;
});
var recursiveSum = function(arr) {
return +arr.reduce(function(a, b) {
return +a + (b && b.reduce ? recursiveSum(b) : +(isNaN(b) ? 0 : b));
}, 0);
};
calc.__proto__.valueOf = function() {
return recursiveSum(args);
};
return calc.bind(this, args);
}
答案 2 :(得分:0)
如果有可能以某种方式做这样的事情。 calc(无限args)(无限args)=一些结果
这可能是我能想象到的最接近你想要的东西:
function calc(a,b) { // we expect a and b to be arrays
if (Array.isArray(a)) { // check if a is an array
if (b === undefined) { // if we don't have a b
return calc.bind(null, a); // return a curried function
}
if (!Array.isArray(b)) { // if b isn't an array
return calc(a, [].splice.call(arguments,1)); // turn all the arguments
// after a into an array and
// call the function again
}
// if both a and b are arrays, just calculate the sum and return it
var aSum = a.reduce(function(p,c) { return p + c },0);
return b.reduce(function(p,c) { return p + c}, aSum);
}
// if a was not an array, turn the arguments into an array and call again
return calc([].splice.call(arguments,0));
}
console.log(calc(1,2)(null)); // 3
console.log(calc(1,2)(3,4)); // 10
console.log(calc(1)(3,4)); // 8
console.log(calc(1,2,3)(null)); // 6
这里的限制是无法执行calc(1,2)
因为它返回一个函数,所以如果你想要结果,唯一的方法是调用它并传递null
。
这里的想法是我们有一个函数,它将采用两个数组a
和b
并将它们加在一起。如果a
不是数组,我们将获取所有传递的参数并将其转换为数组,然后再次调用该函数将该数组作为a
传递。
如果a
是,而数组和b
未定义,那么我们将返回一个使用a
的函数。如果a
是一个数组且b
不是数组,那么我们将所有参数(a
除外)转换为数组并再次调用该函数。如果b
是一个数组,那么我们只是进行计算并返回结果。
答案 3 :(得分:-1)
又一种方式
function sum() {
function add(a, b) {
return a + b;
};
var num = [].reduce.call(arguments, add);
function inner() {
return sum.apply(this, [].concat.apply([num], arguments));
}
inner.toString = inner.valueOf = inner.toJSON = function() {
return num;
}
return inner;
}
function o(prepend, val){
document.getElementById('res').innerHTML += (prepend? (prepend+": "):"")+(typeof val == 'string'? val : JSON.stringify(val)) + '<br />';
}
o('sum(1,2,3)(4,5,6)(7)',sum(1,2,3)(4,5,6)(7));
o('sum(1,2,3)',sum(1,2,3));
o('sum(1)(2,3)', sum(1)(2,3));
o('sum(1,2)(3)',sum(1,2)(3));
o('sum(1,2)(3)+"4"',sum(1,2)(3)+"4");
o('sum(1)(2,3)+4',sum(1)(2,3)+4); //10
<div id="res"></div>