我正在尝试使用递归函数重新定义Javascript的reduce。 这是我的尝试,但不起作用。如果有人可以稍微改变它以使其工作,那将是很好的,因为我会更好地理解它。 (这是functional-javascript-workshop)中的练习。
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 :(得分: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))
答案 1 :(得分:2)
您忘记将累加器的当前值(即initial
)传递到fn
来电。
答案 2 :(得分:1)
正如其他人所说,你错过了将累加器传递给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
&#13;
由于arr.length === 0
,arr.slice(1)
和arr[1]
在处理数组的函数代码中非常常见,因此将这些抽象为函数以降低复杂性和认知负载是很常见的/ p>
// 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
&#13;