1

Я некоторое время работал над этой проблемой во время кодовых войн и использовал repl.it для ее проверки. Это простая одноместная функция Chainer, но он работает только на repl.it, в то время как codewars даст мне TypeError, когда дал этот код:Написание унарного цепочки функций, TypeError на кодоворах, но ошибки на 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; 
    } 
} 

Это говорит мне 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?

+1

Какая ошибка? – zerkms

+0

Это: TypeError: currFunc не является функцией в Array.reduce на doFunc в Object.handleError на ContextifyScript.Script.runInThisContext в Object.exports.runInThisContext –

+0

Вы уверены, что codewars работает именно код, который вы размещены ? – Bergi

ответ

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) 

Ваш код работает иначе и проходит все тесты на 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); 
+0

Спасибо, это имеет смысл! –

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), чтобы понять, как цепочка может быть реализована с помощью функций сгиба.

Смежные вопросы