How to build a tree from flat array of objects

40 views Asked by At

I am trying to build a tree array from a flat array of objects. The category field is structured as an array because it can have n categories

let data = [
  {
    category: [
      "Kat1"
    ],
    otherFields: [
      "Document 1"
    ]
  },
  {
    category: [
      "Kat1"
    ],
    otherFields: [
      "Document 2"
    ]
  },
  {
    category: [
      "Test",
      "Test 2"
    ],
    otherFields: [
      "Document 1"
    ]
  },
  {
    category: [
      "Test",
      "Test 2",
      "Test 3",
      "Test 4",
      "Test 5",
      "Test 6",
      "Test 7",
      "Test 8",
      "Test 9",
      "Test 10",
      "Test 11"
    ],
    otherFields: [
      "Document 1"
    ]
  }
]

It should be

let tree = [
  {
    label: "Kat1",
    children: [
      { label: "Document 1" },
      { label: "Document 2" },
    ]
  },
  {
    label: "Test",
    children: [
      { 
        label: "Test 2",
        children: [
          { label: "Document 1" },
          { 
            label: 'Test 3',
            children: [
              { 
                label: 'Test 4', 
                children: [
                  ...
                ]
              }
            ]
          }
        ]
      },
    ]
  }
]

Is there any article, link solving similar problem? In my last attempt I only got the main categories I fail every time at the documents and sub categories

2

There are 2 answers

0
Botje On BEST ANSWER

A simple recursive function will suffice:

function insert(root, path, label) {
  if (path.length == 0) {
    root.children.push({label})
  } else {
    const [next, ...next_path] = path;
    let next_node = root.children.find(x => x.label == next);
    if (typeof next_node === 'undefined') {
      next_node = {label: next, children: []}
      root.children.push(next_node);
    }
    insert(next_node, next_path, label);
  }
}

let root = { label: "root", children: [] }

for (let o of data) {
    insert(root, o.category, o.otherFields[0])
}
0
Greg On

I believe you'll have to expand your object either with a parent field or a children field. These could reference the index of the parent/child within the array. This is how the GLTF format, for instance, does it.

But if you must use that data structure unchanged, then you could iterate over the array, create a new branch for every category and save them in a map using the category as a key. You'd then create your tree by iterating over the array again and appending the child array for each category with the corresponding value of the map, along with the otherFields attribute.