繁体   English   中英

Javascript递归导致循环结构

[英]Javascript recursion caused circular structure

我有以下2D阵列cells

ID  Name    Parent
1   Bob     0
2   Alice   1
3   John    2
4   Jane    2
5   Jenny   3
6   Jonny   2

我想将其转换为嵌套的JSON格式,这样每个对象都具有以下属性:

  1. 名称

  2. 子代数组,还包括带有名称和子代数组的对象。 数组中没有圆形嵌套; 一个孩子不能有任何父母作为孩子。

这是我写的函数:

function getChildren(node){
    console.log('Getting Children for' + node)
    children = []
    for(i = 0;i < cells.length; i++){
        if(cells[i][2] == node){
            cell = cells[i]
            child = {}
            child.name = cell[1]
            child.children = getChildren(cell[0])
            children.push(child)
        }
    }
    return children
}


text = "ID  Name    Parent\n1   Bob     0\n2   Alice   1\n3   John                  2\n4   Jane    2\n5   Jenny     3\n6   Jonny   2\n"

lines = text.split('\n')
cells = []
for(i = 0; i < lines.length; i++){
    cells[i] = lines[i].split(/\ +/)
}

调用节点6 getChildren(6)上的函数,将得到以下输出:

让孩子参加6
[]

这是正确的,因为节点6没有子节点。

但是在带有孩子的节点上调用该函数,例如getChildren(3)getChildren(3)得到:

让孩子参加3
让孩子参加5

 Object children: Array[1] 0: Object children: Array[1] 0: Object children: Array[1] name: "Jenny" length: 1 name: "Jenny" length: 1 name: "Jenny" 

从控制台输出看来,它似乎调用了正确的函数,但是为什么“ jenny”的对象无限嵌套在所有子对象下?

我想结束一个可以使用JSON.stringify的JSON对象。 getChildren(3)上调用该函数会产生错误

未捕获的TypeError:将圆形结构转换为JSON。

我认为这是因为Jenny的对象无限嵌套在每个孩子下。

将功能更改为以下内容

function getChildren(node){
    console.log('Getting Children for' + node)
    var children = []
    for(i = 0;i<cells.length; i++){
        if(cells[i][2] == node){
            var cell = cells[i]
            child = {}
            child.name = cell[1]
            child.children = getChildren(cell[0])
            children.push(child)
        }}
    return children
}

注意变量声明之前添加的“ var”。 这样可以确保它们被重新初始化,而不是通过函数调用持久化。 这就是造成您的问题的原因。

您可以使用全局变量,并因此,当您递归调用的功能,如儿童儿童的变量可以得到新的价值。 当您退出递归调用时,您将执行以下操作:

children.push(child)

..但子级将获得比您期望的其他值,因此子级也可能具有与递归调用中不同的值(甚至从更深的递归中获得)。

出于同样的原因, i的递归修改将导致问题。

使用var将变量设为函数的局部变量,它将起作用:

function getChildren(node){
    console.log('Getting Children for' + node)
    var children = []
    for(var i = 0;i<cells.length; i++){
        if(cells[i][2] == node){
            var cell = cells[i]
            var child = {}
            child.name = cell[1]
            child.children = getChildren(cell[0])
            children.push(child)
        }}
    return children
}

 function getChildren(node){ var children = [] for(var i = 0;i<cells.length; i++){ if(cells[i][2] == node){ var cell = cells[i] var child = {} child.name = cell[1] child.children = getChildren(cell[0]) children.push(child) }} return children } var text = "ID Name Parent\\n1 Bob 0\\n2 Alice 1\\n3 John 2\\n4 Jane 2\\n5 Jenny 3\\n6 Jonny 2\\n" var lines = text.split('\\n') var cells = [] for(var i = 0; i< lines.length; i++){ cells[i] = lines[i].split(/\\ +/) } console.log(JSON.stringify(getChildren(0), null, 2)); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

如果我理解正确,则可以使用另一种方式解析数据:

//separete the values
var input = [
    [1,   'Bob',     0],
    [2,   'Alice',   1],
    [3,   'John',    2],
    [4,   'Jane',    2],
    [5,   'Jenny',   3],
    [6,   'Jonny',   2]
];

var entities = []; //I belive that the ids are uniq

for (var i = 0; i < input.length; i++){
    var id = input[i][0];
  entities[id] = {
    id: id, 
    name: input[i][1], 
    children : [], 
    parent: input[i][2]
  };
}

for (var i in entities){
    var current = entities[i];
  var parent = entities[current.parent];
  delete current.parent;

  if (parent){
        parent.children.push(current);
  }
}

通过这种方式,您可以通过索引从实体数组中找到特定的元素,或者在解析开始时获取根元素(在elements数组中不包含其父元素的元素)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM