我遇到了一个有趣的问题。编写一个javascript函数,该函数通过多次调用同一函数来返回传递给它的所有参数的总和。
以下是调用函数的方法-
sum(1, 2, 3, 4);
sum(1, 2)(3, 4);
sum(1, 2)(3)(4);
sum(1, 2, 3)(4);
sum(1)(2, 3, 4);
以上所有调用均应正常工作并返回10。
这是我到目前为止所写的内容,但是它仅适用于前两个函数调用sum(1, 2, 3, 4)
和sum(1, 2)(3, 4)
,其余部分都无法使用。
const arr = [];
function sum(...args) {
if (args.length === 4) {
return args.reduce((acc, curr) => {
return (acc = acc + curr);
}, 0);
} else {
arr.push(...args);
return function(...args) {
arr.push(...args);
return sum(...arr);
};
}
}
请有人帮我,这真让我发疯。
谢谢!
答案 0 :(得分:6)
您非常接近。如果您尚未获得至少四个参数,这是使用.bind
方法返回捕获第一个参数的函数的绝好机会。
类似这样:
function sum(...args) {
if (args.length >= 4) {
return args.reduce((acc, curr) => {
return (acc = acc + curr);
}, 0);
} else {
// Bind the arguments you have to this function, and return it:
return sum.bind(null, ...args)
}
}
console.log(sum(1, 2, 3, 4));
console.log(sum(1, 2)(3, 4));
console.log(sum(1, 2)(3)(4));
console.log(sum(1, 2, 3)(4));
console.log(sum(1)(2, 3, 4));
最后,我将更改条件以检查>= 4
,以便在不超过该次数的情况下不会永远咖喱。
答案 1 :(得分:1)
由于不确定的Arity,Currying具有特定的定义行为,不能与可变参数函数很好地混合。但是,在您遇到的特定问题中,您指定了一个Arity(例如4),因此可以知道何时返回结果
const curryN = (n, f, ...xs) =>
(...ys) =>
ys.length >= n
? f (...xs, ...ys)
: curryN (n - ys.length, f, ...xs, ...ys)
const add = (...numbers) =>
numbers.reduce ((a, b) => a + b, 0)
const curryAdd =
curryN (4, add)
console.log
( curryAdd (1) (2) (3) (4) // 10
, curryAdd (1, 2) (3, 4) // 10
, curryAdd (1, 2, 3) (4) // 10
, curryAdd (1) (2, 3, 4) // 10
, curryAdd (1, 2, 3, 4) // 10
)
这是设计程序的脆弱方法,甚至不是 true currying,每个应用程序仅接受1个参数。部分应用程序更好,因为它可以生成行为更可靠的程序
const partial = (f, ...xs) =>
(...ys) =>
f (...xs, ...ys)
const add = (...numbers) =>
numbers.reduce ((a, b) => a + b, 0)
console.log
( partial (add, 1) (2, 3, 4) // 10
, partial (add, 1, 2) (3, 4) // 10
, partial (add, 1, 2, 3) (4) // 10
)
请阅读此related answer,以获取更多信息。