2017-04-25 64 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