skip to Main Content

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

Answers


  1. 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.

    Login or Signup to reply.
  2. 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])
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search