javascript - JavaScript 中的 JSON 递归树

标签 javascript json recursion

我需要一些有关 JavaScript 代码的帮助。 我的目标是编写一个程序来生成一个巨大的二叉树。

在编译之前,我指定了我想要的树的层数,假设 每个对象都有两个子对象(最后一层除外)。

levels=3 的简单可视化: enter image description here

每个对象都有:

-Name - 来自 shema 的第一个字段。它还应包括有关对象编号的信息,

-Type - 来自 shema 的第二个字段。有关物体深度的信息,

-Properties - 关于对象的一些静态信息。在我的情况下,它是相同的,如下所示,

- child

我写了一些代码来准确地从模式中复制树:

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);

但现在我卡住了。我很难让它递归和灵活。

我在我的谷歌光盘上上传了一个输出(json 树): https://drive.google.com/drive/folders/1__nR-AXK7uKRBT4hZtiSWetyaobk72CX?usp=sharing

感谢您提供的任何帮助。

最佳答案

递归树节点生成器

我不是特别喜欢这个实现,因为它不维护你的 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 -> 节点)并通过它访问节点。

希望对你有帮助

关于javascript - JavaScript 中的 JSON 递归树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57757111/

相关文章:

javascript - 从另一个 JavaScript 文件中包含 jQuery

javascript - 如何使用 JavaScript 添加到现有的 FileList 对象?

jquery - 使用 jQuery ajax 时如何向用户显示 JSON HTTP 422 响应?

javascript - 使用express.bodyParser()和passport.js

javascript - 在选项卡的单击功能上初始化猫头鹰轮播

javascript - 谷歌图表和 JSON 数据

json - 更改 JSON.NET 序列化属性名称的方式

c++ - 使用迭代而不是递归的拓扑排序

javascript - 使用递归的加权作业调度

java - 递归Java RLE解压方法【stackoverflow错误】