2

我在代码大战中解决了这个问题一段时间,并使用 repl.it 对其进行了测试。这是一个简单的一元函数链接器,但它只适用于 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));

为什么它不是代码战中的功能有什么原因吗?

4

3 回答 3

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);
于 2016-10-07T18:34:58.597 回答
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)了解如何通过折叠函数实现链接。

于 2016-10-08T14:10:42.783 回答
0

在 ES6 中也有同样的想法。Fun 是一系列函数。

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);
于 2019-03-14T07:37:22.910 回答