关于 JavaScript 中递归数组中最大值的问题

question regarding max value in an array with recursion in JavaScript

目前,我能够得到以下函数,通过递归从数组中检索最大值

const max = ([a,...rest]) => !rest.length || a > max(rest) ? a : max(rest);

console.log(max([-3,3,19,61,99,22,55])); // 99 
console.log(max([32,0,9,87,73])); // 87 
console.log(max([1,6,8])); // 8 

然而,当我尝试通过解构用一个额外的参数“b”重构它时,整个函数将不再正常工作。

const max = ([a,b,...rest]) => !rest.length || a > b ? a : max([b,...rest]);

console.log(max([-3,3,19,61,99,22,55])); // 99 
console.log(max([32,0,9,87,73])); // 32 
console.log(max([1,6,8])); // 6 

谁能解释一下我做错了什么或指出正确的方向。我是递归和编程的新手,所以非常感谢任何帮助:)

更新:

我花了一些时间才弄明白,但这是解构的递归解决方案:

const max = ([a,b,...rest]) => !rest.length && !b ? a : max([b < a ? a : b,...rest]);
  1. 如果“rest”的长度等于“0”且“b”不存在则 return“a”

!rest.length && !b ? a

  1. 否则,递归调用“max”

: max([b < a ? a : b,...rest]);

您想要修复初始递归版本是完全正确的。调用 max (rest) 两次,并对每个后续较小的列表递归执行此操作意味着您调用 max 2n 次,其中 n 是输入的长度。 (更复杂的是,随着 n 是偶数还是奇数而变化,但它仍然以该速率增长。)

所以你确实需要解决这个问题。但是你的尝试有几个致命的缺陷,正如评论中已经报道的那样。首先,很有可能你解构的参数多于列表中的元素。 (在 max ([42])b 会是什么?)其次,当您处理两个元素 (!rest .length) 时,您总是 return 第一个。如果第二个更大呢?

我的方法可能是添加一个取两个元素最大值的辅助函数,然后用它来编写主函数。它可能看起来像这样:

const max2 = (a, b) => a > b ? a : b

const max = ([a, ...rest]) => 
  rest .length == 0 ? a : max2 (a, max (rest)) 

console.log (max ([-3, 3, 19, 61, 99, 22, 55])); // 99 
console.log (max ([32, 0, 9, 87, 73])); // 87
console.log (max ([1, 6, 8])); // 8

当然,我们总是可以使用 Math .max 而不是辅助函数,但这有点作弊。

如果你对辅助函数有强烈的反感,你可以使用默认参数代替。但我认为这段代码比较复杂,而且帮助不大:

const max = ([a, ...rest], b = rest.length ? max (rest) : -Infinity) => 
  rest .length == 0 ? a : a > b ? a : b 

在这里我们使用 -Infinity 作为保证不大于任何其他值的值。这在代码片段版本中也可能有用。现在如果你传递 max 一个空数组,它 returns undefined。如果我们希望它改为 return -Infinity,那么我们可以将 a 默认为 -Infinity:

const max = ([a = -Infinity, ...rest], b = rest.length ? max (rest) : -Infinity) => 
  rest .length == 0 ? a : a > b ? a : b 


max ([]) //=> -Infinity