我有一个带有子节点的JSON树结构,我想知道在给定的结构级别存在多少个节点。我目前有这种递归结构:
assets.json
这不起作用 - 任何帮助都将不胜感激!
答案 0 :(得分:0)
您在此处展示的方法存在一些缺陷。
第一次停止 遇到目标深度的深度将导致只计算那里的第一组子项,这只是一个子集。
使用诸如forEach
之类的迭代函数将在其迭代中进行调用,但它本身不会返回值,并且在回调内部使用return的所示方法也没有效果。
forEach()为每个数组元素执行一次回调函数;与map()或reduce()不同,它总是返回undefined值并且不可链接。典型的用例是在链的末尾执行副作用。 - MDN: Array.prototype.forEach()
更好的方法是按深度分析整个树结构的宽度,并在完成后返回索引值。可以通过在给定深度之后不递归来使其短路,但是我在对象depths
中进行了完整分析以获得完整的示例。
如下所示,这使用IIFE递归树,构建一个对象,其关键是深度,其值是宽度,然后根据原始函数调用的输入深度返回关联的宽度。
var testObj = {
children : [
{ children : [ { children : [ ] } ] },
{ children : [ ] },
{ children : [ { children : [ ] } ] }
]
};
var getNumNodesAtLevel =
function (root, depth) {
var depths = {0:1};
(function recurTree(node,level){
level++;
if(depths[level] == void 0){
depths[level] = node.children.length;
}else{
depths[level] += node.children.length;
}
//optionally short circuit to avoid excessive recursion
//if(level+1 > depth) return;
for(var i = 0; i < node.children.length; i++){
recurTree(node.children[i],level);
}
})(root,0)
return depths[depth];
};
console.log(getNumNodesAtLevel(testObj,1));
console.log(getNumNodesAtLevel(testObj,2));
答案 1 :(得分:0)
你很亲密。你只需将孩子的长度存放在某处。
一旦达到少于所需的一个级别,该函数将返回子项的长度。
树中较高的所有节点只会将从子节点收集的值添加到零并将其传回,直到到达根节点。
var getNumNodesAtLevel = function(node, curr, desired) {
if (curr === (desired - 1))
return node.children.length;
var count = 0;
node.children.forEach(function(child) {
count += getNumNodesAtLevel(child, curr + 1, desired);
});
return count;
};
这种方法的问题是当期望的级别大于树的深度或者它是零时(根级别应该返回1),将返回0。
为了解决这个问题,您可以进行关闭并检查有问题的值。
也无需每次手动发送起始等级。
var test = {
children : [
{ children : [ { children : [ ] } ] },
{ children : [ ] },
{ children : [ { children : [ ] } ] }
]
};
var getNumNodesAtLevel = (function() {
var getNumNodesAtLevel = function(node, curr, desired) {
if (curr === (desired - 1))
return node.children.length;
var count = 0;
node.children.forEach(function(child) {
count += getNumNodesAtLevel(child, curr + 1, desired);
});
return count;
};
return function(root, desired) {
if (desired === 0)
return 1;
var count = getNumNodesAtLevel(root, 0, desired);
if (count === 0)
return null; // you could throw an error here
return count;
};
}());
console.log(getNumNodesAtLevel(test, 0)); // 1
console.log(getNumNodesAtLevel(test, 1)); // 3
console.log(getNumNodesAtLevel(test, 2)); // 2
console.log(getNumNodesAtLevel(test, 3)); // null
console.log(getNumNodesAtLevel(test, 4)); // null
&#13;