3

I have the following JSON, which has files and folders (reserved words) inside to indicate the which are files and folders.

the_name_of_the_folder_itself:
    "files": [array_of_files_]
    "folders": [objects of folders inside this dir]

Its easier to see the JSON itself:

{
    "configfiles": {
        "folders": {
            "dir1": {
                "files": [
                    "data.dat",
                    "data2.dat"
                ]
            },
            "dir2": {
                "folders": {
                    "subffolder": {
                        "files": [
                            []
                        ]
                    },
                    "subffolder_2": {
                        "files": [
                            "other.dat"
                        ]
                    }
                },
                "files": [
                    []
                ]
            }
        },
        "files": [
            []
        ],
        "LoadBase": "barfoo IGNORE THIS"
    }
}

How can I get all the paths and files from that JSON, that means to have an output array with the following elements?

configfiles/
configfiles/dir1/
configfiles/dir1/data.dat
configfiles/dir1/data2.dat
configfiles/dir2/
configfiles/dir2/subffolder/
configfiles/dir2/subffolder_2/
configfiles/dir2/subffolder_2/other.dat

This is my try so far:

function getPathAndFolder(folderPath)
{
    foldersArray = Object.keys(folderPath)
    foldersArray.forEach(function callback(folderName, index, array)
    {
        finalArray.push(folderName)
        filesArray = folderPath[folderName].files
        filesArray.forEach(function callback(fileName, index, array)
        {
            finalPath = folderName + "/" + fileName
        });

        // Call it again
        //getPathAndFolder()

    });
}

finalArray = []
getPathAndFolder(inputJSONobject)

Can someone give me a hand, please?

2
  • Shouldn't it be {folders: { configfiles: { /* ... */ } }? Commented Jun 9, 2020 at 10:17
  • No, the first/main one has no folders before. Commented Jun 9, 2020 at 10:18

1 Answer 1

2

You could create recursive function with for...in loop that takes the data as first parameter and array of keys to ignore when adding to the result where you can pass files, folder etc...

const json = {"configfiles":{"folders":{"dir1":{"files":["data.dat","data2.dat"]},"dir2":{"folders":{"subffolder":{"files":[[]]},"subffolder_2":{"files":["other.dat"]}},"files":[[]]}},"files":[[]],"LoadBase":"barfoo IGNORE THIS"}}

function getPaths(data, ignored = [], prev = '') {
  const result = []

  for (let i in data) {
    let path = prev;

    if (!ignored.includes(i)) {
      if (!Array.isArray(data)) {
        path += (prev.length ? '/' : '') + i
        result.push(path)
      } else if (data[i].length) {
        result.push(path + '/' + data[i])
      }
    }

    if (typeof data[i] === 'object') {
      result.push(...getPaths(data[i], ignored, path))
    }
  }

  return result;
}

const ignored = ['files', 'folders', 'LoadBase']
const result = getPaths(json, ignored);
console.log(result)

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

2 Comments

Just out of curiosity, how does that ... work when you call getPaths again?
Every call of getPaths will always return an array (result variable) so when you create recursive call of the getPaths you want to spread that array (what the getPaths returned) when you push it to result so that you push each individual object and not an array. For better understanding you can see this jsfiddle.net/w1cmrqf8

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.