请解释查找数组深度的递归解决方案

Please explain the recursive solution of finding the depth of an array

我找到了关于这个 link 的解决方案。

由于信誉不足,我无法评论通过评论寻求解释。

function getArrayDepth(value) {
  return Array.isArray(value) ? 
    1 + Math.max(...value.map(getArrayDepth)) :
    0;
}
let testRy = [1,2,[3,4,[5,6],7,[8,[9,91]],10],11,12]

console.log(getArrayDepth(testRy))

能否解释一下为什么要加 1 以及为什么要在上面的函数中使用 Math.max 函数和扩展运算符?这个功能是如何工作的?

testRy中的各个值是:

  • 1
  • 2
  • [3,4,[5,6],7,[8,[9,91]],10]
  • 11
  • 12

第一次执行 getArrayDepthtestRy 时,Array.isArray(value) 将 return 为真。所以因为这是真的,我们知道我们至少有深度 1,所以这就是 1+ 在那里的原因。然后将其添加到 testRy 中每个元素上调用 getArrayDepth 的最大值。这样看起来像:

getArrayDepth(1) => Array.isArray() false => 0
getArrayDepth(2) => Array.isArray() false => 0
getArrayDepth([3,4,[5,6],7,[8,[9,91]],10]) => Array.isArray() true => 1 + next max

所以我们碰到了另一个数组,现在我们至少有另一个深度但是我们需要检查这个数组中是否有数组,所以循环继续这个新数组(它仍然必须完成 testRy , 但是按照它的执行方式,它会先通过这个:

getArrayDepth(3) => Array.isArray() false => 0
getArrayDepth(4) => Array.isArray() false => 0
getArrayDepth([5,6]) => Array.isArray() true => 1 + next max

并重复此过程直到 testRy 结束。

首先,介绍递归:

递归最终会尝试解决您可能遇到的问题的最基本形式,然后逐渐将任何复杂问题缩小到最基本形式。所以你需要以下内容(在你阅读所有内容之前可能没有完全意义):

  1. 您需要解决基本情况。
    • 基本情况也作为终端条件。您想 停止 在某个时候递归调用该函数。一旦达到基本情况,您就不需要再递归了。
  2. 您需要一个还原步骤。你从一个大问题开始,你的目标是找到它的 base 形式并解决它(1. 中的基本情况)。如果当前形式不是基础,那么它是不可解的——你需要稍微减少问题并递归调用函数。

因此,在这种情况下,基本情况 是您获得的值不是数组。因为它不是一个数组,所以它没有深度,因此你 return 为零。解决了!就是这样。

但是,如果您 得到一个数组会怎样?好吧,任何数组都会有 一些 深度。所以,你可以数一然后得到数组的内容。这就是缩减步骤——您已将它从“我有一个未知深度的数组”缩减为“我有我的数组的内容”。当你用内容递归调用 getArrayDepth 时,你将重新评估你是否有一个数组并适当地计数。如果对深度至少为 1 的数组的所有时间求和,则得到深度。

至此,我们可以解决以下事情

输入:42
输出(深度):0
为什么?:这是基本情况 - 它不是数组,所以我们 return 0 并且不递归调用该函数。

输入:[42]
输出(深度):1
为什么?:我们有一个数组 ->
count depth of 1 添加递归调用的结果,内容为 42 -->
这是基本情况 - 它不是数组,所以我们 return 0 并且不递归调用该函数。
回过头来看,我们有 01,总计 1

输入:[[42]]
输出(深度):2
为什么?:我们有一个数组 ->
计算 1 的深度并递归调用内容 [42] -->
我们有一个数组 -->
计算深度 1 并使用内容递归调用 42 --->
这是基本情况 - 它不是数组,所以我们 return 0 并且不递归调用该函数。
回过头来看,我们有 011,总计 2

等等。

现在,至于为什么要用Math.max and Array#map. Since arrays can have many elements, you use .map to call getArrayDepth on each of them. This will cause further recursion to work it out but at the end you will get an array of all the depths of the elements, so ["a", ["b"], [["c"]]] will be transformed into [1, 2, 3]. Since you need to get the total depth, you need the highest number - this is achieved by using Math.max with spread syntax到return的最大值。

将代码翻译成英语听起来像这样:

  1. 输入是数组吗?
    1. yes - 获取每个元素 (value.map(getArrayDepth)) 的最大 (Math.max) 深度并将其递增 1 (1 +) 以说明当前输入数组。
    2. no - 没有数组,因此没有深度,return 0.

展开运算符用于提供 value.map(getArrayDepth) 的数组 return 值作为单独的参数。因为这是 Math.max 所期望的。