Home > Back-end >  Converting "/" sperated data into a tree like structure
Converting "/" sperated data into a tree like structure

Time:01-03

Everyone I'm trying to build something like google drive. I have finished the file upload functionality and I'm now working on the folder upload functionality for which I'm using the HTML file input (I'm using Next.js/React).

 <input
        type="file"
        onChange={(e) => {
          setFiles(e.target.files);
        }}
        webkitdirectory="true"
        directory="true"
        multiple
      />

after selecting a folder and uploading it I'm getting a File list where I have the webkitRelativePath property for each file like this --> "folder/childFolder/file".

now let's say I uploaded a folder which has many files and folders inside it add these are the webkitRelativePath property for all the files

[ 'folder/childFile', 'folder/childFile2', 'folder/childFile3', 'folder/childFolder/childFile4', 'folder/childFolder/childFile5', 'folder/childFolder/grandchildFolder/childFile6', 'folder/childFolder/grandChildFolder/childFile7' ]

using this data I want to create a tree like structure like this -->

{
    name: "folder",
    children: [
      {
        name: "childFile",
        children: [],
      },
      {
        name: "childFile2",
        children: [],
      },
      {
        name: "childFile3",
        children: [],
      },
      {
        name: "childFolder",
        children: [
          {
            name: "childFile4",
            children: [],
          },
          {
            name: "childFile5",
            children: [],
          },
          {
            name: "grandchildFolder",
            children: [
              {
                name: "childFile6",
                children: [],
              },
              {
                name: "childFile7",
                children: [],
              },
            ],
          },
        ],
      },
    ],
  }

I tried using loops and recursion but I was not able to make it work because everyfile is prefixed with the root folder and many more issues

CodePudding user response:

Main part is addPath function that can work both with empty object and with existing tree.

const tree = {};

const list = [
  "folder/childFile",
  "folder/childFile2",
  "folder/childFile3",
  "folder/childFolder/childFile4",
  "folder/childFolder/childFile5",
  "folder/childFolder/grandchildFolder/childFile6",
  "folder/childFolder/grandChildFolder/childFile7"
];

const addPath = (path, tree) => {
  // helper function to create child objects
  const createChild = (name) => ({
    name,
    children: []
  });

  // split path to array of folders and files
  const parts = path.split("/");

  // create tree if empty
  if (!tree.name) {
    Object.assign(tree, createChild(parts[0]));
  }

  // check if root folder is correct
  if (tree.name !== parts[0]) {
    throw new Error(`Root folder is not "${tree.name}"`);
  }
  parts.shift();

  // check and add other path parts
  parts.reduce((current, p) => {
    const child = current.children.find((child) => child.name === p);
    if (child) {
      return child;
    }

    const newChild = createChild(p);
    current.children.push(newChild);
    return newChild;
  }, tree);
};

list.forEach((path) => addPath(path, tree));

console.log(tree);

  • Related