2017-04-25 12 views
1

私は再帰関数を使ってJavascriptのreduceを再定義しようとしています。 これは私の試みですが、うまくいきません。もし誰かが少しだけそれを動作させるためにそれを変更することができます、それは私がそれをよりよく理解するので素晴らしいだろう。 (これはfunctional-javascript-workshopの練習です)。なぜreduce working(JS)の再帰的な定義はありませんか?

/usr/local/lib/node_modules/functional-javascript-workshop/exercises/basic_recursion/exercise.js:13 
    prev[curr] = ++prev[curr] || 1 
          ^

TypeError: Cannot create property 'undefined' on string 'exercitation' 
    at /usr/local/lib/node_modules/functional-javascript-workshop/exercises/basic_recursion/exercise.js:13:29 
    at reduce (/home/david/node-school/functional-workshop/solution.js:7:28) 
    at /usr/local/lib/node_modules/functional-javascript-workshop/exercises/basic_recursion/exercise.js:12:10 
    at obtainResult (/usr/local/lib/node_modules/functional-javascript-workshop/exercises/runner.js:100:21) 
    at Exercise.<anonymous> (/usr/local/lib/node_modules/functional-javascript-workshop/exercises/runner.js:66:27) 
    at next (/usr/local/lib/node_modules/functional-javascript-workshop/node_modules/workshopper-exercise/exercise.js:188:19) 
    at /usr/local/lib/node_modules/functional-javascript-workshop/node_modules/workshopper-exercise/exercise.js:195:7 
    at Exercise.<anonymous> (/usr/local/lib/node_modules/functional-javascript-workshop/exercises/runner.js:34:5) 
    at next (/usr/local/lib/node_modules/functional-javascript-workshop/node_modules/workshopper-exercise/exercise.js:188:19) 
    at /usr/local/lib/node_modules/functional-javascript-workshop/node_modules/workshopper-exercise/exercise.js:195:7 
+0

「if(arr.length)」は機能しますか?私はいつも 'if(arr.length> 0)'を使用します... – Danmoreng

+2

正しいコードを表示していません。エラーは行7の 'solution.js'で呼び出された後、' exercise.js'で発生しています。 –

+1

@Danmoreng、真理値をテストします –

答えて

6

あなたはアキュムレータ更新する必要があります:

function reduce(arr, fn, acc) { 
 
    if (arr.length) { 
 
    var newArr = arr.slice(1, arr.length); 
 
    acc = fn(arr[0], acc) 
 
    return reduce(newArr, fn, acc); 
 
    } else { 
 
    return acc; 
 
    } 
 
} 
 

 
console.log(reduce([1,2,3], (val, sum) => sum + val, 0))

をそれは私に私がどのように解釈するか分からない、次の不可解なエラーメッセージを表示し、与え

function reduce(arr, fn, initial) { 
    if (arr.length) { 
    var newArr = arr.slice(1, arr.length); 
    return reduce(newArr, fn, fn(arr[0])); 
    } else { 
    return initial; 
    } 
} 

module.exports = reduce 

+2

これはあなたの意見男性のようなものです。 (ありがとう!) –

+1

男は守って – thedude

+0

私はあなたがEl Duderino – Greeso

2

あなたは現在のaccの値を渡すのを忘れていますすなわちinitialfnと呼ぶ。

0

他の人が指摘しているように、アキュムレータをfnに渡していませんでした。あなたが好奇心が強いならば、reduceは、単一の三元(?:)式で表現することができます - また、arr.slice(1)1から配列の最後までスライスします。 arr.length === 0arr.slice(1)arr[1]、配列を扱う機能コードにそれほど一般的であるため、この場合には

const reduce = (arr, fn, acc) => 
 
    arr.length === 0 
 
    ? acc 
 
    : reduce(arr.slice(1), fn, fn(acc, arr[0])) 
 

 
const add = (x,y) => x + y 
 

 
console.log(reduce([1,2,3], add, 0)) // 6

をスライスの終わりを指定する必要はありません、それはこれらの機能に抽象化を参照するのが一般的です複雑性と認知的負荷を軽減する

// isEmpty :: [a] -> Boolean 
 
const isEmpty = arr => arr.length === 0 
 

 
// head :: [a] -> a 
 
const head = arr => arr[0] 
 

 
// tail :: [a] -> [a] 
 
const tail = arr => arr.slice(1) 
 

 
// reduce :: ([a], ((b, a) -> b), b) -> b 
 
const reduce = (arr, fn, acc) => 
 
    isEmpty(arr) 
 
    ? acc 
 
    : reduce(tail(arr), fn, fn(acc, head(arr))) 
 

 
// add :: (Number, Number) -> Number 
 
const add = (x,y) => x + y 
 

 
console.log(reduce([1,2,3], add, 0)) // 6

関連する問題