0

I have a data structure that contains nested arrays - I want to display the the data to make it look like a file structure - so nested data is represented as nested files / folders. However on console logging what the recursive function returns does not represent the nested nature of the data structure.

Here is my data structure:

const data = {
  "root": [
    {
      "type": "folder",
      "name": "one",
      "children": [
        {
          "type": "folder",
          "name": "one",
          "children": []
        },
        {
          "type": "file",
          "name": "two",
          "extension": ".txt",
          "preview": "photos.google.com/abc.jpg"
        },
        {
          "type": "file",
          "name": "four",
          "extension": ".txt",
          "preview": "photos.google.com/abc.jpg"
        }
      ]
    },
    {
      "type": "file",
      "name": "two",
      "extension": ".txt",
      "preview": "photos.google.com/abc.jpg"
    },
    {
      "type": "file",
      "name": "three",
      "extension": ".txt",
      "preview": "photos.google.com/abc.jpg"
    },
    {
      "type": "file",
      "name": "four",
      "extension": ".txt",
      "preview": "photos.google.com/abc.jpg"
    }
  ]
}

And my recursive function:

const recurse = (data, children = false) => {
  data.forEach(object => {
    if (object.type === 'folder') {
      recurse(object.children, true)
    }
    if (children) {
      console.log('   ' + object.type + ' ' + object.name);
    } else {
      console.log(object.type + ' ' + object.name);
    }
  })
}

recurse(data.root)

And the console log:

'   folder one'
'   file two'
'   file four'
'folder one'
'file two'
'file three'
'file four'

So the function is printing from the inside out of the structure. What approach should I be using if I want to display it in a way that reflects the nested nature of the data structure?

1
  • Did you try to move the recursion at the end of your iteration (forEach) body? Commented Aug 1, 2019 at 9:28

2 Answers 2

2

@j.xavier.atero was a bit faster than me. :)

I think you have to put the recursion at the end of the function. That way you get the folder one first and then its children.

const recurse = (data, children = false) => {
  data.forEach(object => {
    if (children) {
      console.log('   ' + object.type + ' ' + object.name);
    } else {
      console.log(object.type + ' ' + object.name);
    }
    if (object.type === 'folder') {
      recurse(object.children, true)
    }
  })
}

recurse(data.root)

Update on comment

I would say to add an extra argument for the recurse function so.

const recurse = (data, level = 0) => {
  data.forEach(object => {
    console.log(Array(level).join('   ') + object.type + ' ' + object.name);

    if (object.type === 'folder') {
      recurse(object.children, level + 1)
    }
  })
}

recurse(data.root)

This keeps track of the deepness of the recursive function. You don't even need the check if it's children anymore.

Sign up to request clarification or add additional context in comments.

2 Comments

Awesome, thanks, it works! One more question - what would be the best way to handle adding white space to every level of nesting? So the deeper the nesting the more spaces there are to the left to it looks like a 'real' folder hierarchy?
I would say to add a extra argument for the recurse function so. const recurse = (data, children = false, level = 0) => { and then when you call the recurse function do a plus one. recurse(data, children, level+1) Based on the level you can add spaces. console.log(' '.repeat(level) + object.type + ' ' + object.name); << doesnt work on ie console.log(Array(level).join(' ') + object.type + ' ' + object.name); << works on ie That way you don't even need the if children check.
1

You should print the name of the element before doing the recursion:

const recurse = (data, children = false) => {
  data.forEach(object => {
    if (children) {
      console.log('   ' + object.type + ' ' + object.name);
    } else {
      console.log(object.type + ' ' + object.name);
    }
    if (object.type === 'folder') {
      recurse(object.children, true)
    }
  })
}

recurse(data.root)

Comments

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.