2017-04-25 66 views
1

我試圖重新定義JavaScript的降低使用遞歸函數。 這是我的嘗試,這是行不通的。如果任何人都可以稍微改變它來使它工作,那將是很棒的,因爲我會更好地理解它。 (這是functional-javascript-workshop的練習)。爲什麼這不是遞歸定義的減少工作(JS)?

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 

它給了我下面的神祕的錯誤消息,我不知道如何解釋:

/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

只是想知道:不'如果(arr.length)'工作?我總是用'如果(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))

+2

這就像你的意見人。 (謝謝!) –

+1

夥計遵守 – thedude

+0

我投票給你只是因爲你是El Duderino – Greeso

2

你忘了通過ACC的當前值umulator,即initial,進fn呼叫。

0

正如其他人所指出的,你錯過傳遞累加器fn。如果你很好奇,reduce可以表示爲單個三元組(?:)表達式 - 同樣,arr.slice(1)將從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

因爲arr.length === 0arr.slice(1)arr[1]在功能上的編碼處理陣列以普通切片的結束,這是經常可以看到這些抽象成函數降低複雜性和認知負荷

// 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