HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptModerate

Generate a nested structure based on a list of file paths

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
filepathsnestedgeneratestructurebasedlist

Problem

I'm currently working on a small application, as a learning exercise for a Javascript novice. I need to generate an object based on a folder structure. Here is an example of the folder structure:


RootFolder/FolderA/FolderB/FileA


RootFolder/FolderA/FolderB/FileB


RootFolder/FolderA/FolderB/FolderC/FileA


RootFolder/FolderA/FolderB/FolderC/FileB

The desired resulting object should have the following structure:

{
    RootFolder: {
        FolderA: {
            FolderB: {
                FileA: {},
                FileB: {},
                FolderC: {
                    FileA: {},
                    FileB: {}
                }
            }
        }
    }
};


So far I came up with the following code and it seems to be doing the job, but I'm concerned with 'eval' use and generally believe there is a more elegant way of doing it.



module.exports = {
structure: function(structureArray) {
var generatedObject = {};
for (var i = 0; i



structureArray contains full path strings as in the folder structure example above (e.g. 'RootFolder/FolderA/FolderB/FileA'`)

Solution

You can split each path at / using split and then use reduce() to build that object.



var paths = [
'RootFolder/FolderA/FolderB/FileA',
'RootFolder/FolderA/FolderB/FileB',
'RootFolder/FolderA/FolderB/FolderC/FileA',
'RootFolder/FolderA/FolderB/FolderC/FileB'
]

var obj = {}
paths.forEach(function(path) {
path.split('/').reduce(function(r, e) {
return r[e] || (r[e] = {})
}, obj)
})

console.log(obj)




Here is how you can use this approach to read some directory and all of its nested content and create object from that. This approach is synchronous.

var fs = require('fs');
var path = require('path');

var p = path.resolve('C:\\your\\path\\here')
var result = {}

function buildObject(startPath) {
var dir = fs.readdirSync(startPath)
dir.forEach(function(e) {
var newPath = path.join(startPath, e)

var stat = fs.statSync(newPath);
if (stat && stat.isDirectory()) buildObject(newPath)
if (stat.isFile()) {
newPath.split('\\').reduce(function(r, a) {
return r[a] || (r[a] = {})
}, result)
}
})
}

buildObject(p)
console.log(result)

Context

StackExchange Code Review Q#158134, answer score: 13

Revisions (0)

No revisions yet.