![](/img/trans.png)
[英]how to rearrange recursive json into tree structure with javascript?
[英]A JSON recursive tree in JavaScript
我需要一些有关JavaScript代码的帮助。 我的目标是编写一个程序,该程序将允许生成巨大的二叉树。
编译之前,假设每个对象都有两个子代(最后一个子代除外),则指定希望的树数。
每个对象都有:
-名称-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编号系统(广度优先),因为递归函数本质上是深度优先的,因此一个更简单,可能更好的实现是运行几个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.