簡體   English   中英

編寫一個一元函數鏈接器,codewars 上的 TypeError 但在 repl.it 上沒有錯誤?

[英]Writing a unary function chainer, TypeError on codewars but no error on repl.it?

我在代碼戰爭中解決了這個問題一段時間,並使用 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));

有沒有理由為什么它不是代碼戰中的功能?

我不得不在 codewars 上查找測試。 他們給你這個樣板...

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)

您的代碼可以正常工作並通過 codewars 的所有測試。 這是完整的變化......

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);

雖然@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更能提高性能。 最后,這段代碼也很好理解。 您無需考慮減少iduncurry(rcomp)即可了解如何通過折疊函數實現鏈接。

同樣的想法只是在 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM