簡體   English   中英

JavaScript中的JSON遞歸樹

[英]A JSON recursive tree in JavaScript

我需要一些有關JavaScript代碼的幫助。 我的目標是編寫一個程序,該程序將允許生成巨大的二叉樹。

編譯之前,假設每個對象都有兩個子代(最后一個子代除外),則指定希望的樹數。

簡單可視化級別= 3: 在此處輸入圖片說明

每個對象都有:

-名稱-shema中的第一個字段。 還應包括有關對象編號的信息,

-Type -shema中的第二個字段。 有關物體深度的信息,

-Properties -有關對象的一些靜態信息。 就我而言,情況相同,如下所示:

-兒童

我編寫了一些代碼,可以准確地從模式中重現樹:

var levels = 3; //2^0, 2^1, 2^2
var level_description = [];

for (var i = 0; i < levels; i++) {
    obj = {};
    obj.level = i;
    obj.amount = Math.pow(2, i);
    obj.indexes = [];
    if (i === 0) {
        obj.indexes[0] = 0;
        level_description.push(obj);
    } else {
        for (var j = 0; j < obj.amount; j++) {
            obj.indexes[j] = obj.amount + j - 1;
        }
        level_description.push(obj);
    }
}

console.log(level_description);

var properties = [{
    "name": "trend",
    "value": "true"
}, {
    "name": "unit",
    "value": "g"
}];

var jsonString = JSON.stringify([{
    "name": "Object_" + level_description[0].indexes[0].toString(), //Object_0
    "type": "level_" + level_description[0].level.toString(), //level_0,
    "properties": properties,
    "children": [{
        "name": "Object_" + level_description[1].indexes[0].toString(), //Object_1
        "type": "level_"  + level_description[1].level.toString(), //level_1,
        "properties": properties,
        "children": [{
            "name": "Object_" + level_description[2].indexes[0].toString(), //Object_3
            "type": "level_" + level_description[2].level.toString(), //level_2,
            "properties": properties,
            "children": []
        }, {
            "name": "Object_" + level_description[2].indexes[1].toString(), //Object_4
            "type": "level_" + level_description[2].level.toString(), //level_2,
            "properties": properties,
            "children": []
        }]
    }, {
        "name": "Object_" + level_description[1].indexes[1].toString(), //Object_2
        "type": "level_" + level_description[1].level.toString(), //level_1,
        "properties": properties,
        "children": [{
            "name": "Object_" + level_description[2].indexes[2].toString(), //Object_5
            "type": "level_" + level_description[2].level.toString(), //level_2,
            "properties": properties,
            "children": []
        }, {
            "name": "Object_" + level_description[2].indexes[3].toString(), //Object_6
            "type": "level_" + level_description[2].level.toString(), //level_2,
            "properties": properties,
            "children": []
        }]
    }]
}]);

pm.globals.set('jsonString', jsonString);

但是現在我被困住了。 我很難使其具有遞歸性和靈活性。

我在Google光盤上上傳了輸出(json樹): https : //drive.google.com/drive/folders/1__nR-AXK7uKRBT4hZtiSWetyaobk72CX?usp=sharing

感謝您的任何幫助。

遞歸TreeNode生成器

我並不特別喜歡這種實現,因為它不維護您的TreeNode編號系統(廣度優先),因為遞歸函數本質上是深度優先的,因此一個更簡單,可能更好的實現是運行幾個for循環,一個用於迭代每個級別,並迭代該級別的所需節點。 盡管如此,這是遞歸代碼:

 function TreeNode(name, level, properties, children) { this.name = name; this.level = level; this.properties = properties; this.children = children; } var levels = 3; //2^0, 2^1, 2^2 var tree = new TreeNode("root", 0, {}, []); var tempIndex = 0; function generateArbitraryLevels(parent, levelsRemaining) { // last level if(levelsRemaining == 0) return; var currentLevel = parent.level + 1; parent.children.push( new TreeNode("Object_" + tempIndex++, currentLevel, {}, []) ); generateArbitraryLevels(parent.children[0], levelsRemaining - 1); parent.children.push( new TreeNode("Object_" + tempIndex++, currentLevel, {}, []) ); generateArbitraryLevels(parent.children[1], levelsRemaining - 1); } generateArbitraryLevels(tree, levels); console.log(tree); 


先前的答案(遞歸樹)

因此,我針對此類問題的方法是分別實例化樹中的每個節點,然后將它們彼此關聯。

看看這個例子:

function TreeNode(name, type, properties, children) {
  this.name = name;
  this.type = type;
  this.properties = properties;
  this.children = children;
}

var obj1 = new TreeNode("Object_1", "level_0", {a: 1}, []);
var obj2 = new TreeNode("Object_2", "level_1", {a: 1}, []);
var obj3 = new TreeNode("Object_3", "level_1", {a: 1}, []);
var obj4 = new TreeNode("Object_4", "level_2", {a: 1}, []);
var obj5 = new TreeNode("Object_5", "level_2", {a: 1}, []);

/* TREE:
         1
        / \
       2   3
      / \
     4   5
*/


// push first level
obj1.children.push(obj2);
obj1.children.push(obj3);

// push second level
obj2.children.push(obj4);
obj2.children.push(obj5);



// Now suppose you want to "make it recursive"
// instead of number 2 having 5 as a child we are going to swap that out for 1

/* NEW TREE:
         1
        / \
       2   3
      / \
     4   1
        / \
       ..  ..
*/
// remove 5
obj2.children.pop();
// push 1
obj2.children.push(obj1);

對象變量只是對內存中實際對象的引用,因此在上面的代碼中obj1 === obj2.children[1]true

當然,這只是一個示例,要獲得更大的動力,您應該存儲一個映射(nodeKey-> node)並通過該映射訪問節點。

希望能有所幫助

遞歸樹示例:

 function makeTree(niv, max) { if (max === undefined) { max = niv; } let obj = { name: `n${max - niv}`, childrens:[] }; if (niv < 1) { return obj; } let c1 = makeTree(niv -1, max); obj.childrens.push(c1); let c2 = makeTree(niv -1, max); obj.childrens.push(c2); return obj; } console.log(makeTree(4)); 

我建議這種解決方案:

var cnt = -1;
var properties = {"prop1":"a","prop2":"b"};
var MAX_LEVELS = 3;

function addNode(parent, level){
  cnt = cnt + 1;
  var node = {
    "name": "Object_" + cnt,
    "type": "level_"  + level,
    "properties": properties,
    "children": []
  };

  if (level < MAX_LEVELS){
    addNode(node, level + 1);
    addNode(node, level + 1);
  }

  if (parent){
    parent.children.push(node);
  }
  else {
    return node;
  }
}
let result = addNode(null, 0);
console.log(JSON.stringify(result, null, 4))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM