Lam Thanh
Lam Thanh

Reputation: 25

Convert an array of object to a tree array object using JavaScript

I'm having this data and I want to convert this to tree data with good performance
Each object will have children property which include the id of the element. Check the code below
Input:

let data = [
  {
    "type": "Section",
    "children": [
      "19348bd8-a07c-40fb-b2f5-0a240dd140d3"
    ],
    "_id": "c2c463d9-259e-42e9-bce2-a6735a6ba17d",
  },
  {
    "type": "Row",
    "children": [
      "8bd8a07c-70fb-42f5-8a24-0dd140d36559"
    ],
    "_id": "19348bd8-a07c-40fb-b2f5-0a240dd140d3",
  },
  {
    "type": "Column",
    "children": [
      "a07c70fb-b2f5-4a24-8dd1-40d3655914e3",
      "d8a07c70-fbb2-450a-a40d-d140d3655914"
    ],
    "_id": "8bd8a07c-70fb-42f5-8a24-0dd140d36559",
  },
  {
    "type": "Paragraph",
    "children": [
      "7c70fbb2-f50a-440d-9140-d3655914e3d0",
      "70fbb2f5-0a24-4dd1-80d3-655914e3d02e"
    ],
    "_id": "a07c70fb-b2f5-4a24-8dd1-40d3655914e3",
  },
  {
    "type": "Dropcap",
    "children": [],
    "_id": "7c70fbb2-f50a-440d-9140-d3655914e3d0",
  },
  {
    "type": "Text",
    "children": [],
    "_id": "70fbb2f5-0a24-4dd1-80d3-655914e3d02e",
  },
  {
    "type": "Block",
    "children": [],
    "_id": "d8a07c70-fbb2-450a-a40d-d140d3655914",
  }
]

expected output:

[
        {
            "title": "Section",
            "key": "c2c463d9-259e-42e9-bce2-a6735a6ba17d",
            "children": [
                {
                    "title": "Row",
                    "key": "19348bd8-a07c-40fb-b2f5-0a240dd140d3",
                    "children": [
                        {
                            "title": "Column",
                            "key": "8bd8a07c-70fb-42f5-8a24-0dd140d36559",
                            "children": [
                                {
                                    "title": "Paragraph",
                                    "key": "a07c70fb-b2f5-4a24-8dd1-40d3655914e3",
                                    "children": [
                                        {
                                            "title": "Dropcap",
                                            "key": "7c70fbb2-f50a-440d-9140-d3655914e3d0",
                                            "children": []
                                        },
                                        {
                                            "title": "Text",
                                            "key": "70fbb2f5-0a24-4dd1-80d3-655914e3d02e",
                                            "children": []
                                        }
                                    ]
                                },
                                {
                                    "title": "Block",
                                    "key": "d8a07c70-fbb2-450a-a40d-d140d3655914",
                                    "children": []
                                }
                            ]
                        }
                    ]
                }
            ]
        },
    ]

I have tried to use map and find method to update details for the children property but I can't get further to the expected result. I need some suggestion or guide to solve this https://repl.it/repls/QueasyPureParallelcomputing#index.js

Upvotes: 0

Views: 380

Answers (1)

Nina Scholz
Nina Scholz

Reputation: 386766

You need to

  • collect all children nodes (here a Set noParents with only keys)
  • use a data structure, like an object or map for having the new objects with their associated keys,
  • get only the objects without children,
  • assign nested children with their objects.

const
    data = [{ type: "Section", children: ["19348bd8-a07c-40fb-b2f5-0a240dd140d3"], _id: "c2c463d9-259e-42e9-bce2-a6735a6ba17d" }, { type: "Row", children: ["8bd8a07c-70fb-42f5-8a24-0dd140d36559"], _id: "19348bd8-a07c-40fb-b2f5-0a240dd140d3" }, { type: "Column", children: ["a07c70fb-b2f5-4a24-8dd1-40d3655914e3", "d8a07c70-fbb2-450a-a40d-d140d3655914"], _id: "8bd8a07c-70fb-42f5-8a24-0dd140d36559" }, { type: "Paragraph", children: ["7c70fbb2-f50a-440d-9140-d3655914e3d0", "70fbb2f5-0a24-4dd1-80d3-655914e3d02e"], _id: "a07c70fb-b2f5-4a24-8dd1-40d3655914e3" }, { type: "Dropcap", children: [], _id: "7c70fbb2-f50a-440d-9140-d3655914e3d0" }, { type: "Text", children: [], _id: "70fbb2f5-0a24-4dd1-80d3-655914e3d02e" }, { type: "Block", children: [], _id: "d8a07c70-fbb2-450a-a40d-d140d3655914" }],
    noParents = new Set,
    nodes = data.reduce((r, { _id: key, type: title, children }) => {
        Object.assign(
            r[key] = r[key] || {},
            { title, key, children: children.map(key => (noParents.add(key), r[key] = r[key] || {})) }
        );
        return r;
    }, {}),
    tree = Object.values(nodes).filter(o => !noParents.has(o.key));

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Related Questions