'Getting File Directories as nested Array object
I want to get my file directories as nested array object but i can't seem to figure out how to convert
[
'routes/files',
'routes/files/emptyfolder',
'routes/files/somefolder',
'routes/files/somefolder/example.docx',
'routes/files/test.docx',
'routes/randomdata.json'
]
to
[
{
title: 'routes',
content: [
{
title: 'files',
content: [
{
title: 'empty folder',
content: []
},
{
title: 'somefolder',
content: [
{
title: 'example.docx',
},
]
},
{
title: 'test.docx',
}
],
},
{
title: 'randomdata.json'
}
],
}
]
it looks impossible problem for me to solve. I would love to know how to solve it.
Thank you.
Solution 1:[1]
Here is how I solved it: Not the best solution, but works.
const arr = [
"routes/files",
"routes/files/emptyfolder",
"routes/files/somefolder",
"routes/files/somefolder/example.docx",
"routes/files/test.docx",
"routes/randomdata.json",
];
const arr2 = arr.map((p) => p.split("/"));
const setNestedObjectField = (
obj,
props,
value
) => {
if (!Array.isArray(obj)) {
if (!obj.content) {
obj.content = [];
}
obj = obj.content;
}
for (const propName of props) {
const next = obj.find((el) => el.title === propName);
if (!next) {
console.assert(props.at(-1) === propName);
// last propName
obj.push(value);
} else {
if (!next.content) {
next.content = [];
}
obj = next.content;
}
}
};
const rez = [];
let index = 0;
while (arr2.some((s) => s[index] !== undefined)) {
// arr2 = arr2.filter((a) => a.length);
const layer = arr2.reduce((acc, pathArr) => {
if (pathArr[index] === undefined) return acc;
acc.add(pathArr.slice(0, index + 1).join("/"));
return acc;
}, new Set());
// console.log({ layer });
for (const key of layer) {
setNestedObjectField(rez, key.split("/"), { title: key.split("/").at(-1) });
}
index++;
}
console.log(rez);
Solution 2:[2]
I came across this question and it's an interesting problem, I know it's already been answered, but I wanted to spend a little of my time to solve it my way.
here I leave my code:
function nestedDirectories (arr) {
const splittedArray = arr.map(a => a.split('/'));
return {
mergeObjs: function(target, source) {
for (let key in source) {
if(!target[key]) target[key] = {};
target[key] = this.mergeObjs(target[key], source[key]);
}
return target;
},
buildResponse: function (objMain) {
let arr = [];
for (let key in objMain) {
let o = { title: key, content: [] };
if(key.includes(".")) {
delete o.content;
} else if (Object.keys(objMain[key]).length) {
o.content = this.buildResponse(objMain[key]);
}
arr.push(o);
}
return arr;
},
exec: function () {
let targetObject = {};
splittedArray.forEach(arrParent => {
let strObj = '';
for (let i = arrParent.length - 1; i >= 0 ; i--) {
strObj = `"${arrParent[i]}": {${strObj}}`;
}
let parseObj = JSON.parse(`{${strObj}}`);
targetObject = this.mergeObjs(targetObject, parseObj);
});
return this.buildResponse(targetObject);
}
}
}
and use it like this:
const dirs = [
'routes/files',
'routes/files/emptyfolder',
'routes/files/somefolder',
'routes/files/test.docx',
'routes/randomdata.json',
'routes/files/somefolder/example.docx'
];
const data = nestedDirectories(dirs).exec();
result:
[
{
title: 'routes',
content: [
{
title: 'files',
content: [
{ title: 'emptyfolder', content: [] },
{
title: 'somefolder',
content: [ { title: 'example.docx' } ]
},
{ title: 'test.docx' }
]
},
{ title: 'randomdata.json' }
]
}
]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | valerii15298 |
Solution 2 | Nelsongt77 |