我正在使用reduceRight
方法实现撰写功能,如下所示
const compose = fns => (...args) =>
fns.reduceRight((acc, fn) => fn(acc, ...[args.slice(1)]), args[0]);
const func3 = (x, y) => (y > 0 ? x + 3 : x - 3);
const func2 = x => x ** 2;
const func1 = x => x - 8;
const fnOne = compose([func1, func2, func3])('3', 1);
console.log(fnOne); // should be 1081
const fnTwo = compose([func1, func2, func3])('3', -1);
console.log(fnTwo); //should be -8
第一个函数应该接收两个参数,并将结果作为唯一一个参数返回给下一个函数。问题在于第一个函数将两个参数传递给下一个函数而不是一个。让我知道您是否有解决办法。非常感谢您的帮助。
答案 0 :(得分:1)
您需要在reduceRight()
循环之外调用第一个函数,因为与所有其他函数的调用方式不同。它从...args
获取其参数,其值应用作reduce
的初始累加器参数。
const compose = fns => (...args) => {
let last = fns.pop();
return fns.reduceRight((acc, fn) => fn(acc), last(...args))
};
const func3 = function(x, y) {
console.log(`func3 got ${arguments.length} arguments`);
return (y > 0 ? x + 3 : x - 3);
};
const func2 = function(x) {
console.log(`func2 got ${arguments.length} arguments`);
return x ** 2;
};
const func1 = function(x) {
console.log(`func2 got ${arguments.length} arguments`);
return x - 8;
};
const fnOne = compose([func1, func2, func3])('3', 1);
console.log(fnOne); // should be 1081
const fnTwo = compose([func1, func2, func3])('3', -1);
console.log(fnTwo); //should be -8
答案 1 :(得分:1)
这里的问题是您没有修改args
变量。
让我们详细看看发生了什么:
在您的归约器的第一次呼叫中,acc
变成func3(args[0], ...[args.shift(1)]) === func3(args[0], args[1], args[2], ...)
。
在第二个呼叫中,acc
变成func2(acc, [args.shift(1)])
,即func2(func3(args[0], args[1], args[2], ...), args[1], args[2], ...)
。
您已经知道问题出在哪里:args1
从未从数组中删除,因为Array.slice()
创建了一个副本,并且没有修改实际的数组。
要解决您的问题,您应该使用:
const compose = fns => (...args) =>
fns.reduceRight((acc, fn) => fn(acc, ...args.splice(0, fn.length - 1)), args[0]);