1

In plain javascript, I am trying to create a function that will return a tree structure (json) of a folder, its subfolders and any files. I'm trying to achieve this using recursion. The problem with the below code is that it stops after the first recursive call.

I know that in JS you do references, and I need to create a new object that I pass the values from the previous call to, but I am struggling to do so.

function fun(file, json) {

  var tempJson = {
    'name' : json.name || '',
    'children' : obj.children || new Object()
  };

  if (file.type == 'file') {
    tempJson.type = 'file';
    tempJson.children = {}; // this will be empty, since there are no children
  } 
  else {
    tempJson.type = 'dir';
    var listed = file.listFiles();

    if (listed.length > 0) {
      for each (var item in listed) {
        tempJson.children = fun(item, tempJson);
      }
    } else {
      tempJson.children = {};
    }

  }
  return tempJson;
}


Example

From a directory structure like:

-root
--file1
--dir1
---file1.1
--dir2

I would like to get a json like:

{
name: 'root',
type: 'dir',
children : [
{
    name: 'file1',
    type: 'file',
    children: {}
},
{
    name: 'dir1',
    type: 'dir',
    children: 
    {
         name: 'file1.1',
         type: 'file',
         children: {},
    }
},
name: 'dir2',
type: 'dir',
children: {}
}

First call: var object = new Object(); fun(rootdir, object);

Hope this makes sense. Thanks!

9
  • 1
    For starters, you can't name your function function, but beyond that, you also aren't recursing at all. Commented Nov 6, 2019 at 22:27
  • you mean object not json, right? Commented Nov 6, 2019 at 22:31
  • @Andrew - Thanks for pointing it out. I just edited the name, it now reflects what I meant initially. Commented Nov 6, 2019 at 22:32
  • You probably want children to be an array. Commented Nov 6, 2019 at 22:34
  • @ibrahimmahrir i mean object, yes Commented Nov 6, 2019 at 22:34

1 Answer 1

1

As pointed out in the comments, children should be an array:

function fun(entry) {
  var entryObj = {                                         // construct the object for this entry
    name: entry.name || "",
    type: entry.type,                                      // put the type here instead of using an if
    children: []                                           // children must be an array
  };

  if(entry.type === "dir") {                               // if this entry is a directory
    var childEntries = entry.listFiles();                  // get its child entries
    for(var childEntry of childEntries) {                  // and for each one of them
      entryObj.children.push(fun(childEntry));             // add the result of the call of 'fun' on them to the children array
    }
  }

  return entryObj;
}

Then call it like so:

var tree = fun(rootEntry);
Sign up to request clarification or add additional context in comments.

2 Comments

This is close, but should be modifying obj (currently unused) not creating new entryObj. Either that or there's no need to accept obj.
@BrandonHill good point. I'll edit, thanks. I got rid of it alltogether.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.