1

I'm in the process of trying to filter a hierarchy given a list of leaf level nodes. To explain a bit bitter I've attached an image.

hierarchy

Given a hierarchy, and given a list of leaf level nodes like seen in the left side of the picture, filter the hierarchy to only show the leaf level nodes and their respective paths back to the root.

The data looks like so:

[{"NodeId":"1","id":"1","dimension":"Hierarchy Number","name":"root","children":[{"NodeId":"1.1","id":"1.1","dimension":"Hierarchy Number","name":"1.1","parent":"1","children":[{"NodeId":"1.1.1","id":"1.1.1","dimension":"Hierarchy Number","name":"1.1.1","parent":"1.1"},{"NodeId":"1.1.2","id":"1.1.2","dimension":"Hierarchy Number","name":"1.1.2","parent":"1.1"},{"NodeId":"1.1.3","id":"1.1.3","dimension":"Hierarchy Number","name":"1.1.3","parent":"1.1"}]},{"NodeId":"1.2","id":"1.2","dimension":"Hierarchy Number","name":"1.2","parent":"1","children":[{"NodeId":"1.2.1","id":"1.2.1","dimension":"Hierarchy Number","name":"1.2.1","parent":"1.2"},{"NodeId":"1.2.2","id":"1.2.2","dimension":"Hierarchy Number","name":"1.2.2","parent":"1.2","children":[{"NodeId":"1.2.2.1","id":"1.2.2.1","dimension":"Hierarchy Number","name":"1.2.2.1","parent":"1.2.2"},{"NodeId":"1.2.2.2","id":"1.2.2.2","dimension":"Hierarchy Number","name":"1.2.2.2","parent":"1.2.2"}]}]}]}]

Each child also has a reference back to its parent inside (except this root node)

CStreet
  • 365
  • 1
  • 5
  • 20
  • what is with `1.1.3` and `1.2.1`? do you have some more data whcih reflects the given stuicture in the picture? have you tried anything? – Nina Scholz Mar 28 '18 at 15:20
  • `The data looks like so:` Does it?, sorry not seen that sort of data structure before in Javascript. – Keith Mar 28 '18 at 15:31
  • I've edited the data portion to reflect actual data structure @Keith, – CStreet Mar 28 '18 at 17:44
  • @NinaScholz 1.1.3 and 1.2.1 are part of the original tree, once the those would be filtered out because they wouldn't be part of the tree created by traversing back through the given leaf nodes – CStreet Mar 28 '18 at 17:45

1 Answers1

0

You could filter the array by mutating the children properties.

If you need not to mutate the array, you need to take a copy of the tree or build new objects while iterating.

function filter(root, leafs) {
    return root.filter(function (node) {
        var temp;
        if (leafs.includes(node.NodeId)) {
            return true;
        }
        temp = filter(node.children || [], leafs);
        if (temp.length) {
            node.children = temp;
            return true;
        }
    });
}

var tree = [{ NodeId: "1", id: "1", dimension: "Hierarchy Number", name: "root", children: [{ NodeId: "1.1", id: "1.1", dimension: "Hierarchy Number", name: "1.1", parent: "1", children: [{ NodeId: "1.1.1", id: "1.1.1", dimension: "Hierarchy Number", name: "1.1.1", parent: "1.1" }, { NodeId: "1.1.2", id: "1.1.2", dimension: "Hierarchy Number", name: "1.1.2", parent: "1.1" }, { NodeId: "1.1.3", id: "1.1.3", dimension: "Hierarchy Number", name: "1.1.3", parent: "1.1" }] }, { NodeId: "1.2", id: "1.2", dimension: "Hierarchy Number", name: "1.2", parent: "1", children: [{ NodeId: "1.2.1", id: "1.2.1", dimension: "Hierarchy Number", name: "1.2.1", parent: "1.2" }, { NodeId: "1.2.2", id: "1.2.2", dimension: "Hierarchy Number", name: "1.2.2", parent: "1.2", children: [{ NodeId: "1.2.2.1", id: "1.2.2.1", dimension: "Hierarchy Number", name: "1.2.2.1", parent: "1.2.2" }, { NodeId: "1.2.2.2", id: "1.2.2.2", dimension: "Hierarchy Number", name: "1.2.2.2", parent: "1.2.2" }] }] }] }];

console.log(filter(tree, ['1.1.1', '1.1.2', '1.2.2.1', '1.2.2.2']));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Without mutating the original tree.

function filter(root, leafs) {
    var result = [];
    root.forEach(function (node) {
        var children;
        if (leafs.includes(node.NodeId)) {
            result.push(node);
            return;
        }
        children = filter(node.children || [], leafs);
        if (children.length) {
            result.push(Object.assign({}, node, { children }));
        }
    });
    return result;
}

var tree = [{ NodeId: "1", id: "1", dimension: "Hierarchy Number", name: "root", children: [{ NodeId: "1.1", id: "1.1", dimension: "Hierarchy Number", name: "1.1", parent: "1", children: [{ NodeId: "1.1.1", id: "1.1.1", dimension: "Hierarchy Number", name: "1.1.1", parent: "1.1" }, { NodeId: "1.1.2", id: "1.1.2", dimension: "Hierarchy Number", name: "1.1.2", parent: "1.1" }, { NodeId: "1.1.3", id: "1.1.3", dimension: "Hierarchy Number", name: "1.1.3", parent: "1.1" }] }, { NodeId: "1.2", id: "1.2", dimension: "Hierarchy Number", name: "1.2", parent: "1", children: [{ NodeId: "1.2.1", id: "1.2.1", dimension: "Hierarchy Number", name: "1.2.1", parent: "1.2" }, { NodeId: "1.2.2", id: "1.2.2", dimension: "Hierarchy Number", name: "1.2.2", parent: "1.2", children: [{ NodeId: "1.2.2.1", id: "1.2.2.1", dimension: "Hierarchy Number", name: "1.2.2.1", parent: "1.2.2" }, { NodeId: "1.2.2.2", id: "1.2.2.2", dimension: "Hierarchy Number", name: "1.2.2.2", parent: "1.2.2" }] }] }] }];

console.log(filter(tree, ['1.1.1', '1.1.2', '1.2.2.1', '1.2.2.2']));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Could you help me on this problem https://stackoverflow.com/questions/52039222/how-to-implement-hierarchical-multilevel-datatable-in-javascript?noredirect=1#comment91031196_52039222 – Varun Sharma Aug 28 '18 at 06:22