[英]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.