Search code examples
javascriptarraysobjectjavascript-objects

Javascript forEach an Array of Object recursive



i need some help at looping over an Object with Array of Objects

Here is an example Object:

const node = {
    documents: [{
        name: "test1"
    }],
    children: [{
        documents: [{
            name: "test2"
        }],
        children: [{
            documents: [{
                name: "test3"
            }],
            children: []
        }]
    }]
};


My Problem
I tried some of the solutions from here but it's not quite what I need. Basically i want to move every object from the documents Array into the childrens Array.
I already got that but currently its only doing it in the firts Object so not recursive...
I cant figure it out without creating an Frankenstein-ish code...
I tried like i mentioned before i used

Array.concat()

to append documents to children but only in the first Object.
What it should look like

const node = {
    children: [
    {
    name: "test1"
    },
    {
    children: [
        {
      name: "test2"
      },
      {
      children: [
        {name: "test3"}
      ]
      }
    ]
    }
  ]
};

Now in every "depth" the documents were "appended" to children.
And that should happen for every children key (depth).

Is someone kind enough to help me out?


EDIT:

I guess my example is not good enough. Here is some actual data:

      const node = {
        id: 1,
        name: "Root Node",
        documents: [
          { name: "Doc Root 1", id: 1234 },
          { name: "Doc Root 2", id: 1235 }
        ],
        children: [
          {
            id: 2,
            name: "Sub Node Node1",
            documents: [
              { name: "Doc SubNote 1 1", id: 1236 },
              { name: "Doc SubNote 1 2", id: 1237 }
            ],
            children: [{
              id: 3,
              name: "Sub Sub Node Node 1",
              documents: [
                { name: "Doc SubSubNote 1 1", id: 1238 },
                { name: "Doc SubSubNote 1 2", id: 1239 }
              ],
              children: null,
              addTreeNodeDisabled: true,
              addLeafNodeDisabled: true,
              editNodeDisabled: true,
              delNodeDisabled: true,
            }],
            addTreeNodeDisabled: true,
            addLeafNodeDisabled: true,
            editNodeDisabled: true,
            delNodeDisabled: true,
          }
        ],
        addTreeNodeDisabled: true,
        addLeafNodeDisabled: true,
        editNodeDisabled: true,
        delNodeDisabled: true,
      };

Solution

  • You could concat a copy of documents with the childrens by calling the function again.

    var f = ({ documents, children, ...o }) => {
            children = [...(documents || []), ...(children || [])].map(f);
            return children.length
                ? { ...o, children }
                : o;
        },
        data = { id: 1, name: "Root Node", documents: [{ name: "Doc Root 1", id: 1234 }, { name: "Doc Root 2", id: 1235 }], children: [{ id: 2, name: "Sub Node Node1", documents: [{ name: "Doc SubNote 1 1", id: 1236 }, { name: "Doc SubNote 1 2", id: 1237 }], children: [{ id: 3, name: "Sub Sub Node Node 1", documents: [{ name: "Doc SubSubNote 1 1", id: 1238 }, { name: "Doc SubSubNote 1 2", id: 1239 }], children: null, addTreeNodeDisabled: true, addLeafNodeDisabled: true, editNodeDisabled: true, delNodeDisabled: true, }], addTreeNodeDisabled: true, addLeafNodeDisabled: true, editNodeDisabled: true, delNodeDisabled: true, }], addTreeNodeDisabled: true, addLeafNodeDisabled: true, editNodeDisabled: true, delNodeDisabled: true },
        result = f(data);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }