2

I am using node.js and as a side project i am creating a module that reads a .json file ,parse it then create directory structure based on object properties & object values.

Object properties(keys) would be the path to itself/to files & object values would be the list of files for that path

i have tried to recurse downwards through the object but i dont know how i extract the path from the inner-most object of each object

Also object would be dynamic as would be created by the user.

var path = 'c:/templates/<angular-app>'; var template = { //outline of 'angular-app' src:{ jade:['main.jade'], scripts:{ modules:{ render:['index.js'], winodws:['index.js'], header:['header.js' ,'controller.js'], SCSS:['index.scss' ,'setup.scss'], } } }, compiled:['angular.js','angular-material.js' ,'fallback.js'], built:{ frontEnd:[],//if the array is empty then create the path anyways backEnd:[], assets:{ fontAwesome:['font-awesome.css'], img:[], svg:[] } } } //desired result... let out = [ 'c:/template name/src/jade/main.jade', 'c:/template name/src/scripts/index.js', 'c:/template name/src/scripts/modules/render/index.js', 'c:/template name/compiled/angular.js', 'c:/template name/compiled/angular-material.js', 'c:/template name/compiled/fallback.js', 'c:/template name/built/frontEnd/', 'c:/template name/built/backEnd/', //...ect... ];

2 Answers 2

1

Here's an example on how you can write this recursively:

var path = 'c:/templates'; var template = { //outline of 'angular-app' src: { jade: ['main.jade'], scripts: { modules: { render: ['index.js'], winodws: ['index.js'], header: ['header.js', 'controller.js'], SCSS: ['index.scss', 'setup.scss'], } } }, compiled: ['angular.js', 'angular-material.js', 'fallback.js'], built: { frontEnd: [], //if the array is empty then create the path anyways backEnd: [], assets: { fontAwesome: ['font-awesome.css'], img: [], svg: [] } } } function recurse(item, path, result) { //create default output if not passed-in result = result || []; //item is an object, iterate its properties for (let key in item) { let value = item[key]; let newPath = path + "/" + key; if (typeof value === "string") { //if the property is a string, just append to the result result.push(newPath + "/" + value); } else if (Array.isArray(value)) { //if an array if (value.length === 0) { //just the directory name result.push(newPath + "/"); } else { //itearate all files value.forEach(function(arrayItem) { result.push(newPath + "/" + arrayItem); }); } } else { //this is an object, recursively build results recurse(value, newPath, result); } } return result; } var output = recurse(template, path); console.log(output);

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

Comments

1

My solution for this problem would be as follows;

function getPaths(o, root = "", result = []) { var ok = Object.keys(o); return ok.reduce((a,k) => { var p = root + k + "/"; typeof o[k] == "object" && o[k] !== null && Array.isArray(o[k]) ? o[k].length ? o[k].forEach(f => a.push(p+=f)) : a.push(p) : getPaths(o[k],p,a); return a; },result); } var path = 'c:/templates/', template = { //outline of 'angular-app' src:{ jade:['main.jade'], scripts:{ modules:{ render:['index.js'], winodws:['index.js'], header:['header.js' ,'controller.js'], SCSS:['index.scss' ,'setup.scss'], } } }, compiled:['angular.js','angular-material.js' ,'fallback.js'], built:{ frontEnd:[],//if the array is empty then create the path anyways backEnd:[], assets:{ fontAwesome:['font-awesome.css'], img:[], svg:[] } } }, paths = getPaths(template,path); console.log(paths);

It's just one simple function called getPaths Actually it has a pretty basic recursive run. If your object is well structured (do not include any properties other than objects and arrays and no null values) you may even drop the typeof o[k] == "object" && o[k] !== null && line too. Sorry for my unorthodox indenting style but this is how i find to deal with the code more easy when doing ternaries, logical shortcuts and array methods with ES6 arrow callbacks.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.