Skip to content Skip to sidebar Skip to footer

Turn An Array With File Path To Object As Mentioned

I need a javascript function to turn an array with file path string to object as follows: let files = [ 'Folder/file.ext', 'Folder/file2.ext', 'Folder/file3.ext', 'Folde

Solution 1:

Having a tree represented as an array is a little inconvenient because you need to search the array each time to find the appropriate node, which would be inefficient for large arrays. On option is to just build a tree object in one pass and then do a second pass to just take the Object.values. Here's an example of that:

let files = ["Folder/file.ext","Folder/file2.ext","Folder/file3.ext","Folder/nestedfolder/file.ext","Folder2/file1.ext","Folder2/file2.ext","file1.ext","file2.ext","file3.ext",];

functionaddPath(arr, obj = {}){
    let component = arr.shift()
    let current = obj[component] || (obj[component] = {text:component})
    if (arr.length) {
        addPath(arr, current.children || (current.children = {}))
    }
    return obj
}

functionmakeArray(obj){
    let arr = Object.values(obj)
    arr.filter(item => item.children).forEach(item => {
        item.children = makeArray(item.children)
    })
    return arr
}

// make treelet treeObj = files.reduce((obj, path) =>addPath(path.split('/'), obj), {})
// convert to arraylet arr = makeArray(treeObj)

console.log(arr)

An alternative is using find() which will work and may be easier to read…but may be less efficient because you need to search the result array on each pass:

let files = ["Folder/file.ext","Folder/file2.ext","Folder/file3.ext","Folder/nestedfolder/file.ext","Folder2/file1.ext","Folder2/file2.ext","file1.ext","file2.ext","file3.ext",];

functionaddPath(pathcomponents, arr ){
    let component = pathcomponents.shift()
    let comp = arr.find(item => item.text === component)
    if (!comp) {
        comp =  {text: component}
        arr.push(comp)
    }
    if(pathcomponents.length){
       addPath(pathcomponents, comp.children || (comp.children = []))
    }
    return arr
}



let res = files.reduce((arr, path) =>addPath(path.split('/'), arr), [])

console.log(res)

Solution 2:

Here's my take, one function, no recursion:

constlistToTree = files =>
  files.map(file => file.split('/'))
  .reduce((out, path) => {
    let top = out;
    while (path.length > 0) {
      let node = path.shift();
      if (top.findIndex(n => n.text === node) === -1) {
        top.push({
          text: node
        });
      }

      if (path.length > 0) {
        let index = top.findIndex(n => n.text === node);
        top[index] = top[index] || {};
        top[index].children = top[index].children || [];
        top[index].children.push({
          text: path[0]
        });
        top = top[index].children;
      }
    }
    return out;
  }, []);

let files = [
  'Folder/file.ext',
  'Folder/file2.ext',
  'Folder/file3.ext',
  'Folder/nestedfolder/file.ext',
  'Folder2/nestedfolder1/nestedfolder2/file1.ext',
  'Folder2/file2.ext',
  'file1.ext',
  'file2.ext',
  'file3.ext'
];

console.log(listToTree(files));

Post a Comment for "Turn An Array With File Path To Object As Mentioned"