【问题标题】:Why isn't this recursive definition of reduce working (JS)?为什么这个reduce 工作(JS)的递归定义不是?
【发布时间】:2017-09-22 15:40:03
【问题描述】:

我正在尝试使用递归函数重新定义 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

【问题讨论】:

  • 只是想知道:if(arr.length) 有效吗?我总是用if(arr.length &gt; 0)...
  • 您没有向我们展示正确的代码。在第 7 行的 solution.js 中调用后,错误发生在 exercise.js 中。
  • @Danmoreng,它测试真实值
  • 什么是fn? initial 应该是数组中元素的index 吗?
  • @guest271314 fn 是用于减少数组的任何函数

标签: javascript recursion reduce


【解决方案1】:

你需要更新累加器:

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】:

您忘记将累加器的当前值(即initial)传递给fn 调用。

【讨论】:

    【解决方案3】:

    正如其他人所指出的,您错过了将累加器传递给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 === 0、arr.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

    【讨论】:

      猜你喜欢
      • 2012-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多