簡體   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