skip to Main Content

I have an huge input array of nodes with children array that contains a list of id of nodes, I’ve got help to create a tree function that loop through the input array to create a tree.

the input :

[
  {
    "neo4jId": "1",
    "nodeName": "A",
    "children": ["12", "13", "14"]
  },

  {
    "neo4jId": "12",
    "nodeName": "AA",
    "children": ["1", "21", "22", "23"]
  },
  {
    "neo4jId": "13",
    "nodeName": "AB",
    "children": ["1"]
  },
  {
    "neo4jId": "14",
    "nodeName": "AC",
    "children": ["12"]
  },
  {
    "neo4jId": "21",
    "nodeName": "AAA",
    "children": ["1"]
  },
  {
    "neo4jId": "22",
    "nodeName": "AAB",
    "children": ["13"]
  },
  {
    "neo4jId": "23",
    "nodeName": "AAC",
    "children": []
  }
]

The expected output is :

[
  {
    "key": "1",
    "data": {
      "nodeName": "A"
    },
    "children": [
      {
        "key": "12",
        "data": {
          "nodeName": "AA"
        },
        "children": [
          {
            "key": "21",
            "data": {
              "nodeName": "AAA"
            },
            "children": [
              {
                "key": "1",
                "data": { "nodeName": "A" },
                "children": []
              }
            ]
          },
          {
            "key": "22",
            "data": {
              "nodeName": "AAB"
            },
            "children": [
              {
                "key": "13",
                "data": { "nodeName": "AB" },
                "children": [
                  {
                    "key": "1",
                    "data": { "nodeName": "A" },
                    "children": []
                  }
                ]
              }
            ]
          },
          {
            "key": "23",
            "data": {
              "nodeName": "AAC"
            },
            "children": []
          },
          {
            "key": "1",
            "data": {
              "nodeName": "A"
            },
            "children": []
          }
        ]
      },
      {
        "key": "13",
        "data": {
          "nodeName": "AB"
        },
        "children": [
          {
            "key": "1",
            "data": {
              "nodeName": "A"
            },
            "children": []
          }
        ]
      },
      {
        "key": "14",
        "data": {
          "nodeName": "AC"
        },
        "children": [
          {
            "key": "12",
            "data": { "nodeName": "AA" },
            "children": [
              {
                "key": "21",
                "data": {
                  "nodeName": "AAA"
                },
                "children": [
                  {
                    "key": "1",
                    "data": { "nodeName": "A" },
                    "children": []
                  }
                ]
              },
              {
                "key": "22",
                "data": {
                  "nodeName": "AAB"
                },
                "children": [
                  {
                    "key": "13",
                    "data": { "nodeName": "AB" },
                    "children": [
                      {
                        "key": "1",
                        "data": { "nodeName": "AA" },
                        "children": []
                      }
                    ]
                  }
                ]
              },
              {
                "key": "23",
                "data": {
                  "nodeName": "AAC"
                },
                "children": []
              },
              {
                "key": "1",
                "data": {
                  "nodeName": "A"
                },
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
]

For the moment, and with this function :

const getTree = (data = []) => {
  const getObject = (key) =>
      (({ children, noRecursion = [], ...o }) => ({
        ...o,
        children: [...children.map(getObject), ...noRecursion.map((key) => ({ ...r[key], children: [] }))],
      }))(r[key]),
    c = new Set(),
    r = Object.fromEntries(data.map(({ neo4jId: key, children = [], ...data }) => [key, { key, data, children }])),
    keys = Object.keys(r);

  keys.forEach((k) => {
    r[k].children.forEach((l) => {
      if (r[l].children.length < r[k].children.length) {
        r[l].noRecursion = [...r[l].children];
        r[l].children.length = 0;
      }
    });
  });

  keys.forEach((k) => r[k].children.forEach(Set.prototype.add, c));

  console.log(keys.filter((k) => !c.has(k)).map(getObject));

  return keys.filter((k) => !c.has(k)).map(getObject);
};

The expected output is not printed correctly..

I’m looking for this architecture :
expected output

For each node, I should verify if it not contains his parents id’s OR if it not contains a children’s root node, if not I display a tree normaly inside, else I should display the tree founded (from root node or from parents nodes) but with only one level (to avoid recursion)

The root parent is alyways the first item of input data

And the output should be an array with only one node

have you an idea how to achieve this with javascript ?

3

Answers


  1. const data = [{"neo4jId":"1","nodeName":"A","children":["12","13","14"]},{"neo4jId":"12","nodeName":"AA","children":["1","21","22","23"]},{"neo4jId":"13","nodeName":"AB","children":["1"]},{"neo4jId":"14","nodeName":"AC","children":["12"]},{"neo4jId":"21","nodeName":"AAA","children":["1"]},{"neo4jId":"22","nodeName":"AAB","children":["13"]},{"neo4jId":"23","nodeName":"AAC","children":[]}]
    
    const [root] = data
    
    const f = ({neo4jId:key, nodeName, children:c}, s={}) => ({
      key,
      data:{nodeName},
      children:s[key]?[]:(s[key]=1, c.map(key =>
        data.find(({neo4jId:i}) => i===key)).map(i=>f(i,{...s})))
    })
    
    console.log(f(root))
    Login or Signup to reply.
  2. This ain’t a tree, this is a directed graph and looks like this. (Arrows pointing from "parent" to "child")

    tree

    And a snippet how to resolve it:

    let data = [
      {
        "neo4jId": "1",
        "nodeName": "node_parent",
        "children": ["2", "3", "4", "5"]
      },
    
      {
        "neo4jId": "2",
        "nodeName": "children 2",
        "children": ["1"]
      },
      {
        "neo4jId": "3",
        "nodeName": "children 3",
        "children": ["1", "2"]
      },
      {
        "neo4jId": "4",
        "nodeName": "children 4",
        "children": ["5"]
      },
      {
        "neo4jId": "5",
        "nodeName": "children 5",
        "children": ["6"]
      },
      {
        "neo4jId": "6",
        "nodeName": "children 6",
        "children": ["4"]
      }
    ]
    
    const byId = {};
    
    for(let item of data) 
      byId[item.neo4jId] = item;
    
    for(let item of data) 
      item.children = item.children.map(id => byId[id]);
      
    // check your browsers console
    // don't attempt to log this in the snippet, 
    // it will crash the snippet.
    
    console.log(byId[1]);  // let's start somewhere
    Login or Signup to reply.
  3. An approach.

    const
        getTree = data => {
            const
                getNodes = (keys, seen = []) => keys.map(key => ({
                    ...nodes[key],
                    children: seen.includes(key)
                        ? []
                        : getNodes(nodes[key].children, [...seen, key])
                })),
                nodes = Object.fromEntries(data.map(({ neo4jId: key, children, ...data }) => [key, { key, data, children }]));
                
            return getNodes([data[0].neo4jId]);
        },
        data = [
            { neo4jId: "1",  nodeName: "A",   children: ["12", "13", "14"] },
            { neo4jId: "12", nodeName: "AA",  children: ["1", "21", "22", "23"] },
            { neo4jId: "13", nodeName: "AB",  children: ["1"] },
            { neo4jId: "14", nodeName: "AC",  children: ["12"] },
            { neo4jId: "21", nodeName: "AAA", children: ["1"] },
            { neo4jId: "22", nodeName: "AAB", children: ["13"] },
            { neo4jId: "23", nodeName: "AAC", children: [] }
        ],
        tree = getTree(data);
    
    console.log(tree);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search