关于 JavaScript .reduce 方法的累加器的问题

A question on JavaScript .reduce method's accumulator

我正在研究这个问题,以使用 reduce 方法创建一个函数,该函数将获取数组中的最大数字。

导师的回答是:

const numbers = [1, 2, 3, 4, 4, 5, 1, 3, 4];
const max = getMax(numbers);
console.log(max);
function getMax(array) {
   if (array.length === 0) return undefined;
   return array.reduce((accumulator, current) => {
       return (accumulator > current) ? accumulator : current
}); 

我试过这样的事情:

 return array.reduce((accumulator, current) => {
    if (accumulator < current)
        console.log(accumulator, current);
        return accumulator = current;
});   

我添加了 console.log(累加器,电流)因为我想看看我的代码发生了什么。日志显示如下:

console.log of my code

1 2
2 3
3 4
4 5
1 3
3 4
4

问题 1。我想知道为什么我的函数没有给出正确的输出(returned 4,而不是正确的输出 5)。 "accumulator" 在循环中被分配为 5 时不应该保持 5 吗?

问题2、为什么if语句下面已经有return,函数中还需要return(或在前面加return)数组?

尝试使用Math.max方法:

const numbers = [1, 2, 3, 4, 4, 5, 1, 3, 4]
numbers.reduce((acc, rec) => Math.max(acc, rec))

//5

function max(numbers) {
  return list.reduce((acc, rec) => acc > rec ? acc : rec)
}

如果您需要在没有 Math.max 的情况下找到最大值。

您在 if 语句后没有使用 { ... },所以 只有 第一行 console.log(...) 在条件为遇见了。 accumlator = current 行总是出现在每次迭代中。使用命令式 if 语句 时必须使用 return。但是,当使用函数式样式 表达式 时,您可以跳过 return,即 (accumulator, current) => accumulator < current ? current : accumulator 表示 "if accumulator is less than current, return current, else return accumulator".

考虑这个分解的程序。当我们将 max 视为一个独立的函数时,它可以帮助我们准确地看到 reduce 期望的函数类型 -

const max = (a = 0, b = 0) =>
  a < b               // if a is less than b
    ? b               // return b
    : a               // otherwise return a
 
const getMax = (numbers = []) =>
  numbers.length === 0          // if numbers.length is zero
    ? undefined                 // return undefined
    : numbers.reduce(max)       // otherwise return reduction

console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined

我们可以看到reduce是产生下面的计算-

// given
[1, 2, 3, 4, 4, 5, 1, 3, 4]

// starting with the first two
r = max(1, 2)

// then the next number
r = max(r, 3)

// then the next number
r = max(r, 4)

// then the next number
r = max(r, 4)

或没有中间件r = ... -

max(max(max(max(max(max(max(max(1, 2), 3), 4), 4), 5), 1), 3), 4)

我们可以写 getMax 而不用 reduce,如果我们想要 -

const max = (a = 0, b = 0) =>
  a < b
    ? b
    : a
 
const getMax = (numbers = []) =>
  numbers.length === 0 // without any numbers,
    ? undefined        // there can be no max.
: numbers.length === 1 // if we only have one,
    ? numbers[0]       // we already know max.
    : max(numbers[0], getMax(numbers.slice(1))) // else

console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined

或者您可能还没有学习 slice。您可以使用数组索引 i 来遍历数组 -

const max = (a = 0, b = 0) =>
  a < b
    ? b
    : a
 
const getMax = (numbers = [], i = 0) =>
  numbers.length === 0    // without any numbers,
    ? undefined           // there can be no max.
: i + 1 >= numbers.length // if the next i is not in bounds,
    ? numbers[i]          // this is the last number
    : max(numbers[i], getMax(numbers, i + 1)) // else

console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined

也可以使用解构赋值-

const max = (a = 0, b = 0) =>
  a < b
    ? b
    : a
 
const getMax = ([ num, ...more ] = []) =>
  more.length === 0
    ? num
    : max(num, getMax(more))
    
console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined

这可能会告诉您如何发明自己的 reduce -

const max = (a = 0, b = 0) =>
  a < b
    ? b
    : a
 
const reduce = (f, a = [], i = 0) =>
  a.length === 0    // without any numbers,
    ? undefined     // there can be no reduction.
: i + 1 >= a.length // if the next i is not in bounds,
    ? a[i]          // this is the last element
    : f(a[i], reduce(f, a, i + 1)) // else

const getMax = (numbers = []) =>
  reduce(max, numbers) // <-- our reduce!

console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined