查找深层嵌套数组的深度

时间:2020-08-21 08:13:48

标签: javascript arrays recursion nested

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

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

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

我该如何实现?我尝试使用递归,但不知道如何找到 嵌套的孩子最多。

谢谢。

1 个答案:

答案 0 :(得分:3)

假设没有循环引用,则可以尝试这样的操作

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))

如果有一些循环引用,我们的功能将无法正常工作,因此可能需要相应地进行调整。检测循环引用是一项艰巨的任务。如果对此不采取任何措施,该函数将抛出最大调用堆栈大小超出错误。

为了在不执行任何其他功能的情况下进行处理,可以使用已经存在的本机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