我在代码大战上解决了这个问题一段时间,并使用repl.it来测试它。它是一个简单的一元函数chainer,但它只适用于repl.it,而codewars在给出这段代码时会给我一个TypeError:
function chained(functions) {
var funcs = Array.prototype.slice.call(arguments);
return function (value){
var finalValue = funcs.reduce(function(prevVal, currFunc){
return currFunc(prevVal);
}, value);
return finalValue;
}
}
它告诉我currFunc不是一个函数,但使用以下测试代码我在repl.it中运行时得到了正确的答案:
function f1(x){ return x*2 }
function f2(x){ return x+2 }
function f3(x){ return Math.pow(x,2) }
console.log(chained(f1,f2,f3)(0));
为什么它不是代码战中的功能?
答案 0 :(得分:1)
我不得不在代码大战中查找测试。他们给你这个样板......
function chained(functions) {
//FIXME
}
查看测试,您可以看到函数正在数组中传递......
Test.assertEquals( chained([f1,f2,f3])(0), 4 )
Test.assertEquals( chained([f1,f2,f3])(2), 36 )
Test.assertEquals( chained([f3,f2,f1])(2), 12 )
你犯的错误是......
var funcs = Array.prototype.slice.call(arguments);
...仅在chained
被调用时才有效...
chained(f1,f2,f3)
您的代码可以正常工作并通过代码战中的所有测试。这是完全改变......
function chained(functions) {
var funcs = Array.prototype.slice.call(arguments);
return function (value){
var finalValue = funcsfunctions.reduce(function(prevVal, currFunc){
return currFunc(prevVal);
}, value);
return finalValue;
}
}
最后,这是我的解决方案^ _ ^
const id = x => x;
const uncurry = f => (x,y) => f (x) (y);
const rcomp = f => g => x => g (f (x));
const chained = fs => fs.reduce(uncurry(rcomp), id);
答案 1 :(得分:0)
虽然@ naomik的解决方案是正确答案并且应该被接受,但我只是想使用老式的ES3分享另一种解决方案:
function chained(functions) {
return function(x) {
var fs = functions, i = fs.length, y = x;
while (i > 0) y = fs[--i](y);
return y;
};
}
这只是为了表明在这种特殊情况下你真的不需要使用reduce
来编写简洁的代码。此外,使用while
循环比使用reduce
更有利于性能。最后,这段代码也很容易理解。您不需要精神上与减少id
和uncurry(rcomp)
有关,以了解折叠函数如何实现链接。
答案 2 :(得分:0)
与ES6相同的想法。乐趣是一系列功能。
const chained = fun => {
return input => {
return fun.reduce((acc, currentFun) => currentFun(acc), input);
}
};
,虽然难读但漂亮的现代JS版本:
const chained = fun => input => fun.reduce((acc, currentFun) => currentFun(acc), input);