【问题标题】:Find deep nested array depth查找深层嵌套数组深度
【发布时间】:2020-12-10 14:48:10
【问题描述】:

我有一个嵌套数组。如下所示: 我想找到这个嵌套数组的深度,这意味着子元素有最深的嵌套子元素。

let arr = [
   {
     name: 'tiger',
     children: [{
       name: 'sinba',
       children: [{
         name: 'cute',
         children: []
        }]
      }]
    },
    {
      name: 'lion',
      children: []
    }
]

在这种情况下,深度为 3tiger 有 3 级。所以深度是3

我怎么能做到这一点?我尝试使用递归,但不知道如何找到 拥有最多嵌套的子节点。

提前致谢。

【问题讨论】:

    标签: javascript arrays recursion nested


    【解决方案1】:

    假设没有循环引用,你可以试试这样的

    let arr = [{
        name: 'tiger',
        children: [{
          name: 'sinba',
          children: [{
            name: 'cute',
            children: []
          }]
        }]
      },
      {
        name: 'lion',
        children: []
      }
    ]
    
    function count(children) {
      return children.reduce((depth, child) => {
        return Math.max(depth, 1 + count(child.children)); // increment depth of children by 1, and compare it with accumulated depth of other children within the same element
      }, 0); //default value 0 that's returned if there are no children
    }
    
    console.log(count(arr))

    如果有一些循环引用,我们的函数将无法工作,因此可能需要相应地调整它。检测循环引用是一项艰巨的任务。如果什么都不做,函数会抛出 Maximum call stack size exceeded 错误。

    为了在没有任何额外功能实现的情况下处理它,您可以使用已经存在的本机 JSON.stringify 来执行此操作。仅当您尝试序列化我们可以自己处理的 BigInt 值或当对象是循环的(这正是我们想要的)时,stringify 选项才会抛出异常。

    let arr = [{
      name: 'tiger',
      children: []
    }]
    
    function testCircular(arr){
      try {
        BigInt.prototype.toJSON = function() { return this.toString() } // Instead of throwing, JSON.stringify of BigInt now produces a string
        JSON.stringify(arr);
        return false;
      }
      catch (e) {
        // will only enter here in case of circular references
        return true;
      }
    }
    
    function count(children) {
      if (testCircular(children)) return Infinity;
      return children.reduce((depth, child) => {
        return Math.max(depth, 1 + count(child.children)); // increment depth of children by 1, and compare it with accumulated depth of other children within the same element
      }, 0); //default value 0 that's returned if there are no children
    }
    
    console.log(count(arr)) // normally counting
    arr[0].children = arr; // creates circular reference
    console.log(count(arr)) // counting for circular

    【讨论】:

    • 为什么是Math.max 和比较?
    • @KunalMukherjee reduce 函数迭代了所有子元素,我需要比较计算子元素的结果,以了解哪个元素最多,并且只保留它的信息。当然,我一次最多只能比较 2 个元素,我可能可以使用一个简单的 if else 语句,但 max 也可以工作
    • 不错的解决方案!
    • 请注意BigInt 扩展不会将JSON.parse 大数返回BigInt。例如JSON.parse("999999999999999999999999999999999999999999") 返回1e+42
    • 这里仅用于消除错误抛出而不是实际解析数据
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 2019-05-05
    • 2014-06-10
    • 1970-01-01
    相关资源
    最近更新 更多