1

Ich habe für kurze Zeit an Code Wars gearbeitet und es mit repl.it getestet. Es ist eine einfache einstellige Funktion chainer, aber es funktioniert nur auf repl.it, während codewars mir eine Typeerror wenn Sie diesen Code gegeben geben werden:Schreiben eines unären Funktionsträgers, TypeError bei Codewars, aber kein Fehler bei repl.it?

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

es mir erzählt currFunc ist keine Funktion, aber mit dem folgenden Testcode ich erhalte die richtigen Antworten, während in repl.it ausgeführt wird:

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

gibt es einen Grund, warum es nicht eine Funktion in codewars ist?

+1

Was ist der genaue Fehler? – zerkms

+0

Dieses: Typeerror: currFunc ist keine Funktion bei Array.reduce bei doFunc bei Object.handleError bei ContextifyScript.Script.runInThisContext bei Object.exports.runInThisContext –

+0

Sind Sie sicher, dass codewars genau den Code ausgeführt wird Sie auf dem Laufenden ? – Bergi

Antwort

1

Ich musste den Test auf Codewars nachschlagen. Sie geben Ihnen diese vorformulierten ...

function chained(functions) { 
    //FIXME 
} 

bei den Tests der Suche können Sie sehen, dass die Funktionen in einem Array übergeben werden ...

Test.assertEquals(chained([f1,f2,f3])(0), 4) 
Test.assertEquals(chained([f1,f2,f3])(2), 36) 
Test.assertEquals(chained([f3,f2,f1])(2), 12)

Der Fehler, den Sie gemacht ist .. .

var funcs = Array.prototype.slice.call(arguments); 

..., die nur so aufgerufen wurde ... wenn chained funktionieren würde

chained(f1,f2,f3) 

Ihr Code sonst funktioniert und übergibt alle Tests auf codewars. Hier ist die komplette Änderung ...

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

Schließlich, hier ist meine Lösung^_^

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

Danke, das macht Sinn! –

0

Während @ naomik-Lösung ist die richtige Antwort und sollte akzeptiert werden, ich wollte nur teilen eine alternative Lösung mit guten altmodischen ES3:

function chained(functions) { 
    return function(x) { 
     var fs = functions, i = fs.length, y = x; 
     while (i > 0) y = fs[--i](y); 
     return y; 
    }; 
} 

Dies ist nur um zu zeigen, dass Sie nicht wirklich 01 verwenden müssen, um in diesem speziellen Fall prägnanten Code zu schreiben. Außerdem ist die Verwendung einer while-Schleife für die Leistung besser als die Verwendung von reduce. Schließlich ist dieser Code auch sehr verständlich. Sie müssen nicht mental mit reduzierenden id und uncurry(rcomp) jonglieren, um zu verstehen, wie Verkettung durch Faltfunktionen implementiert werden kann.

Verwandte Themen