如何比较嵌套在对象数组中的数组中的值,与对象属性进行比较?

3

我有一张图表,其中的节点可以连接到多个其他节点。

每个节点都是数组中的一个对象。在每个节点的对象中,有一个包含与此节点链接的所有节点的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的节点是根节点。
问题在于节点的子数组包含所有链接到它的节点。深度为2的节点指向深度为1的节点。
因此,我想在节点对象中创建一个新数组,比如nodes.next,并且去掉指向深度低于自身的节点的子节点。
经过一段时间的努力,我有两种方法可以实现。首先,我检查子数组的长度是否大于1。然后,我依赖于事实,即不应将children数组中的节点推送到next数组中,该节点恰好位于索引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": [] }
];

1
你能提供一个样本输出格式吗? - Eddie
明白了,已更新问题。 - Vincent
2个回答

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);
.as-console-wrapper { max-height: 100% !important; top: 0; }


我已经遇到过几次这样的问题,试图用几个for循环来解决它,使它变得比实际更加复杂。而你只用了几行代码就解决了它,并且正确的id也被返回给了nodes.next。我需要多练习使用map和js数组方法,这确实帮助我朝着正确的方向前进,谢谢你。 - Vincent

1
幸运的是,由于对象中明确注明了深度,因此很容易将节点映射到另一个数组并检查每个子节点的深度,过滤掉深度较小的节点。提前制作每个节点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);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接