Search code examples
javascriptnode.jsreactjsrecursionredux

convert list of strings to recursive/nested dict/json object (file explorer type system)


I have a Redux Store that is currently returning me a list of strings that represent folders example below"

/Documents/Pictures/Test

/Documents/Pictures/Test2

/System

/Libraries/Node

and I would like to cover this to a dict/json object in javascript so that it looks like:

data = {        id:'0',
        name:"/",
        child:[{
              id:'1',
              name:"Documents",
              child:[
                id:'2',
                name:"Pictures",
                child:[{
                  id:'3',
                  name:"Test",
                  child:[]
                },
                {
                  id:'3',
                  name:"Test2",
                  child:[]
                }]
                ]},
              id:'1',
              name:"System",
              child:[]
              
              
              ]}
.... so on and so forth

I have spent two days on this, and I have played around with using Object.keys but can't seem to get it to work and matching but can't seem to get it to work.

this is my current code that "works" but does not do it recursively

convertThePaths(){
    var pathRow = this.props.paths[0]; //grabbing the first array to test (/documents/pictures/test) is in here
    
    pathArray = pathRow.split("/") //splits between the /'s to get folder names
    
    var data = { id:'0',name:"/",child:[]}
    for (var j = 0; pathArray.length;j++){
      data.child.push(
      id: j
      name: pathArray[j],
      child: [] // need recursive here? maybe call convertPaths?
      )
}

id does not matter as long as its unique, I know how to do this in python but not javascript. any help is appreciated! I feel like I am over complicating this...


Solution

  • Here's how to do it below. I explain with code comments

    const convertThePaths = (pathRows,data,index)=>{
        // Once index is the size of the pathRows were done
        if (pathRows.length===index){
            return;
        }
        
       let pathArray = pathRows[index].split("/"); //splits between the /'s to get folder names
       pathArray = pathArray.slice(1,pathArray.length); // remove empty string at start of arr.
    
       // Cur depth of dictionary
       let curData = data; 
       // Loop through all paths in pathArray
       for (const pathName of pathArray){
           // Filter for the pathName in the children 
           let childInlst = curData["child"].filter(obj=>obj.name===pathName);
           
           // If list is empty no such child was found so add it 
           if (childInlst.length===0){
               // Add child that doesn't exist yet
               curData["child"].push({
                   "name":pathName,
                   "id":`${parseInt(curData["id"])+1}`,
                   "child":[],
               })
           }
           // Now child must exist so filter it and it will be index 0 of the list 
           curData = curData["child"].filter(obj=>obj.name===pathName)[0];
    
           // Then repeat
       }
        
        // Now repeat the same step with the next path in pathRows
        convertThePaths(pathRows,data,index+1);
    }
     
    // Prints out the data recursively
    const printData = (data)=>{
        console.log(data.name+" "+data.id);
        if (data.child.length===0){
            return;
        }
        for (const child of data.child){
            printData(child)
        }
    }
    
    
    const Main=()=>{
        const pathRows = [
           "/Documents/Pictures/Test",
           "/Documents/Pictures/Test2",
           "/System",
           "/Libraries/Node",
        ]
        
        // Data start state
        const data = {"id":"0","name":"/","child":[]};
        
        // Recursive function
        convertThePaths(pathRows,data,0);
        
        // function to print data out recursively
        printData(data);
        
        
        
    }
    
    Main();
    
    

    Output printed out recursively

    / 0
    Documents 1
    Pictures 2
    Test 3
    Test2 3
    System 1
    Libraries 1
    Node 2