[英]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格式,这样每个对象都具有以下属性:
名称
子代数组,还包括带有名称和子代数组的对象。 数组中没有圆形嵌套; 一个孩子不能有任何父母作为孩子。
这是我写的函数:
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
让孩子参加5Object 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.