【骚操作】JS带你飞,嵌套数组深度计算轻松搞定!

您所在的位置:网站首页 javascript三维数组遍历 【骚操作】JS带你飞,嵌套数组深度计算轻松搞定!

【骚操作】JS带你飞,嵌套数组深度计算轻松搞定!

2023-11-26 14:06| 来源: 网络整理| 查看: 265

cover.png

前言

在前端开发中,经常会遇到需要处理多维嵌套的数据结构。而对于这些多维嵌套的数据结构,往往需要计算出它们的深度,用于方便后续处理。本文将介绍使用JavaScript实现计算多维嵌套数组深度的方法。

理论知识

在了解具体实现前,先来了解一下相关的理论知识:多维数组的深度。所谓数组的深度,就是指这个数组里面嵌套了多少层子数组。如下图所示:

[1, 2, 3, 4] // 深度为 1 [[1, 2], [3, 4]] // 深度为 2 [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] // 深度为 3

可以看出,第一种情况只有一层,第二种情况有两层,第三种情况有三层。

实现思路

根据上述定义,计算一个数组的深度其实就是递归遍历每一层子数组,并不断加一的过程。因此,我们可以采用递归的思想,实现如下:

function getDepth(arr) { if (!Array.isArray(arr)) { // 判断是否为数组 return 0; } let depth = 1; // 初始化深度为 1 for (let i = 0; i < arr.length; i++) { const cur = arr[i]; if (Array.isArray(cur)) { // 如果当前元素仍为数组,递归遍历 const curDepth = getDepth(cur) + 1; depth = Math.max(depth, curDepth); } } return depth; }

上述代码中,首先进行了类型判断,如果不是数组,则直接返回“0”;否则,逐层遍历每一层子数组,通过递归调用函数计算出每个子数组的深度,并记录最大深度。

实例演示

我们可以利用上述方法对以下多维嵌套数组进行深度计算:

const arr1 = [1, 2, 3, 4]; // 深度为 1 const arr2 = [[1, 2], [3, 4]]; // 深度为 2 const arr3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]; // 深度为 3 console.log(getDepth(arr1)); // 输出 1 console.log(getDepth(arr2)); // 输出 2 console.log(getDepth(arr3)); // 输出 3

在控制台输出结果如下:

1 2 3

此外,我们还可以对一些嵌套层数较深的数组进行计算:

const arr4 = [[[[1, 2], [3, 4]], [[5, 6], [7, 8]]], [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]; // 深度为 4 console.log(getDepth(arr4)); // 输出 4 性能优化

在实际开发中,如果处理的数据量很大,单纯使用递归的方法可能会耗费大量时间和内存资源。因此,在设计算法时应该尽可能地减少时间复杂度和空间复杂度。

以下是一些可能比较好的优化方案:

方案一:队列迭代

队列迭代法同样可以获取多维嵌套数组的深度,而且有时候运行速度更快。我们可以使用一个队列来存储每一层子数组,并不断出队并将其所有元素压入队列中,直到队列为空为止。我们可以通过记录队列的大小来控制深度的增加,具体实现如下:

function getDepthByQueue(arr) { if (!Array.isArray(arr)) { // 判断是否为数组 return 0; } let depth = 1; // 初始化深度为 1 const queue = [arr]; // 将初始数组放入队列中 while (queue.length) { // 如果队列不为空 const curLevelSize = queue.length; for (let i = 0; i < curLevelSize; i++) { const cur = queue.shift(); // 出队一个子数组 if (Array.isArray(cur)) { queue.push(...cur); // 将其中所有元素入队 } } depth++; // 深度加一 } return depth - 1; // 最后在队列为空时,depth 多增加了一次,故需要减一 } 方案二:reduce计数

通过使用reduce方法,可以实现对多维嵌套数组的深度进行计数。在这种方法里,我们只需要遍历每一个元素,并让其值等于当前递归所得到的深度加一即可。

function getDepthByReduce(arr) { if (!Array.isArray(arr)) { // 判断是否为数组 return 0; } return arr.reduce(function(pre, cur) { const curDepth = getDepthByReduce(cur) + 1; return Math.max(pre, curDepth); }, 1) } 异常处理

在正常情况下,多维嵌套数组的深度是可以被正常计算的。但是在某些边界条件下,我们需要对计算过程进行异常处理:

边界条件一:空数组

对于空数组,其深度为0。

console.log(getDepth([])); // 输出 0 边界条件二:不是数组

如果传入的值不是数组类型,返回0即可。

console.log(getDepth("test")); // 输出 0 console.log(getDepth({ a: 1 })); // 输出 0 console.log(getDepth(123)); // 输出 0 边界条件三:无限递归

在某些特殊情况下,可能会出现无限递归的错误。例如一个由自己本身构成的数组,此时就会导致函数陷入死循环。因此,在编写代码时需要避免这种恶性递归行为。

const test = []; test.push(test); console.log(getDepth(test)); // 此处会出现无限递归的错误

为了避免无限递归的问题,可以设置一个计数器。当函数调用次数超过一定值时,抛出异常并阻止递归的继续进行。

function getDepthWithLimit(arr, limit = 10000) { let count = 0; function calculateDepth(cur) { if (!Array.isArray(cur)) { return 0; } if (count++ > limit) { // 超过极限次数则返回 Infinity throw new Error("too much recursive"); } const curDepth = Math.max(...cur.map(calculateDepth)) + 1; return curDepth; } try { return calculateDepth(arr); } catch (e) { console.warn(e.message); return Infinity; } }

在函数中增加计数器,每经过一次递归就自增,如果达到某个条件(limit)就抛出异常,并阻止递归的执行。最后用try...catch来捕获异常。

结尾

我们可以看到使用JavaScript计算多维嵌套数组的深度十分方便。只需采用递归的思路,遍历每一个子数组,并记录最大深度即可。

但需要注意的是,在实际开发中,如果多维嵌套层数过深,会导致递归调用栈溢出的问题。因此,在实现该方法时需要考虑到性能优化和异常处理。

以下是实现时的一些注意点:

尽量避免对传入参数进行修改,否则可能会影响其它部分代码。 在递归过程中要注意边界条件的处理,以防止无限递归或者数组越界的情况发生。 对于反复出现的计算结果可以进行缓存,以提高代码执行效率。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3