我有一个包含节点的图表,可以连接到其他多个节点。
每个节点都是数组中的对象。在每个节点的对象中是一个数组,其中包含链接到此节点及其深度的所有节点的ID:
const nodes = [
{ "id": 37, "depth": 0, "children": [210, 395, 265], "next": [] },
{ "id": 210, "depth": 1, "children": [37, 260, 259, 391],"next": [] },
{ "id": 256, "depth": 2, "children": [265], "next": [] },
{ "id": 259, "depth": 2, "children": [210, 397, 396], "next": [] },
{ "id": 260, "depth": 2, "children": [210], "next": [] },
{ "id": 265, "depth": 1, "children": [37, 256, 388, 394, 271, 269], "next": [] },
{ "id": 269, "depth": 2, "children": [265], "next": [] },
{ "id": 271, "depth": 2, "children": [265], "next": [] },
{ "id": 388, "depth": 2, "children": [265], "next": [] },
{ "id": 391, "depth": 2, "children": [210], "next": [] },
{ "id": 394, "depth": 2, "children": [265], "next": [] },
{ "id": 395, "depth": 1, "children": [37], "next": [] },
{ "id": 396, "depth": 3, "children": [259, 413], "next": [] },
{ "id": 397, "depth": 3, "children": [259], "next": [] },
{ "id": 413, "depth": 4, "children": [396], "next": [] }
];
我想遍历深度为0的节点为根的图。
问题是节点的children数组包含链接到它的所有节点。深度为2的节点返回深度为1的节点。
所以我想在节点的对象中创建一个新数组,让我们说nodes.next并删除那些指向深度低于自身的节点的子节点。
我用两种方式让它工作了一段时间。在第一次我检查子数组的长度是否大于1.然后我依赖于子数组中不应该被推到下一个节点的事实,恰好是在索引0处。这不是很可靠。
我在第二个解决方案中发现的困难是检查子节点中节点的深度是否高于当前迭代中节点的深度。如果是,请将其推送到节点的下一个阵列。我希望你能以更好的方式展示如何做到这一点,因为这个解决方案无论如何都不是很好:
let currentDepth;
let childDepth;
let currentID;
let childID;
const getChildDepth = (childID) => {
for (let i = 0; i < nodes.length; i++) {
if (childID === nodes[i].id) {
childDepth = nodes[i].depth
}
}
};
for (let i = 0; j < nodes.length; j++) {
currentDepth = nodes[j].depth;
currentID = nodes[j].id;
if (nodes[j].children.length > 1) {
for (let i = 0; i < nodes[j].children.length; i++) {
childID = nodes[j].children[i];
getChildDepth(childID);
if (childDepth > currentDepth) {
nodes[j].next.push(childID)
}
}
}
}
示例输出:
const nodes = [
{ "id": 37, "depth": 0, "children": [210, 395, 265], "next": [210, 395, 265] },
{ "id": 210, "depth": 1, "children": [37, 260, 259, 391],"next": [260, 259, 391] },
{ "id": 256, "depth": 2, "children": [265], "next": [] },
{ "id": 259, "depth": 2, "children": [210, 397, 396], "next": [397, 396] },
{ "id": 260, "depth": 2, "children": [210], "next": [] },
{ "id": 265, "depth": 1, "children": [37, 256, 388, 394, 271, 269], "next": [256, 388, 394, 271, 269] },
{ "id": 269, "depth": 2, "children": [265], "next": [] },
{ "id": 271, "depth": 2, "children": [265], "next": [] },
{ "id": 388, "depth": 2, "children": [265], "next": [] },
{ "id": 391, "depth": 2, "children": [210], "next": [] },
{ "id": 394, "depth": 2, "children": [265], "next": [] },
{ "id": 395, "depth": 1, "children": [37], "next": [] },
{ "id": 396, "depth": 3, "children": [259, 413], "next": [413] },
{ "id": 397, "depth": 3, "children": [259], "next": [] },
{ "id": 413, "depth": 4, "children": [396], "next": [] }
];
答案 0 :(得分:2)
您可以将Map
作为节点的参考,并通过深度检查过滤子项来更新next
。
var nodes = [{ id: 37, depth: 0, children: [210, 395, 265], next: [] }, { id: 210, depth: 1, children: [37, 260, 259, 391], next: [] }, { id: 256, depth: 2, children: [265], next: [] }, { id: 259, depth: 2, children: [210, 397, 396], next: [] }, { id: 260, depth: 2, children: [210], next: [] }, { id: 265, depth: 1, children: [37, 256, 388, 394, 271, 269], next: [] }, { id: 269, depth: 2, children: [265], next: [] }, { id: 271, depth: 2, children: [265], next: [] }, { id: 388, depth: 2, children: [265], next: [] }, { id: 391, depth: 2, children: [210], next: [] }, { id: 394, depth: 2, children: [265], next: [] }, { id: 395, depth: 1, children: [37], next: [] }, { id: 396, depth: 3, children: [259, 413], next: [] }, { id: 397, depth: 3, children: [259], next: [] }, { id: 413, depth: 4, children: [396], next: [] }],
references = new Map(nodes.map(n => [n.id, n]));
nodes.forEach(node => node.next = node.children.filter(
id => references.get(id).depth > node.depth
));
console.log(nodes);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 1 :(得分:1)
幸运的是,由于depth
在对象中被明确指出,因此map
节点到另一个数组很简单并检查每个子节点的深度,过滤掉那些节点的深度深度较小。提前为每个节点ID及其深度Map
制作一个以便于查找:
const nodes = [
{ "id": 37, "depth": 0, "children": [210, 395, 265]},
{ "id": 210, "depth": 1, "children": [37, 260, 259, 391]},
{ "id": 256, "depth": 2, "children": [265]},
{ "id": 259, "depth": 2, "children": [210, 397, 396]},
{ "id": 260, "depth": 2, "children": [210]},
{ "id": 265, "depth": 1, "children": [37, 256, 388, 394, 271, 269]},
{ "id": 269, "depth": 2, "children": [265]},
{ "id": 271, "depth": 2, "children": [265]},
{ "id": 388, "depth": 2, "children": [265]},
{ "id": 391, "depth": 2, "children": [210]},
{ "id": 394, "depth": 2, "children": [265]},
{ "id": 395, "depth": 1, "children": [37]},
{ "id": 396, "depth": 3, "children": [259, 413]},
{ "id": 397, "depth": 3, "children": [259]},
{ "id": 413, "depth": 4, "children": [396]}
];
const depthsById = new Map(nodes.map(node => [node.id, node.depth]));
const nodesWithNext = nodes.map((node) => {
const { depth } = node;
const next = node.children.filter(childId => depthsById.get(childId) > depth);
return { ...node, next};
});
console.log(nodesWithNext[0].next);
console.log(nodesWithNext[1].next);
console.log(nodesWithNext[10].next);
console.log('-------\n-------');
console.log(nodesWithNext);
&#13;