admin管理员组文章数量:1319480
I need a javascript function to turn an array with file path string to object as follows:
let files = [
"Folder/file.ext",
"Folder/file2.ext",
"Folder/file3.ext",
"Folder/nestedfolder/file.ext",
"Folder2/file1.ext",
"Folder2/file2.ext",
"file1.ext",
"file2.ext",
"file3.ext",
];
listToTree(files);
And It should output an array with an object as follows:
[
{
text: "Folder",
children: [
{text: "file.ext"},
{text: "file1.ext"},
{text: "file2.ext"},
{text: "nestedfolder", children: [{text: "file.ext"}]},
]
},
{
text: "Folder2",
children: [
{text: "file1.ext"},
{text: "file2.ext"},
]
},
{text: "file1.ext"},
{text: "file2.ext"},
{text: "file3.ext"}
];
Here is the current function I am using. but it is not quite there.
function listToTree(files) {
let filestmp = files.map(file => {
if (typeof file === "string") return file;
return file.path
});
let filesl = filestmp.map(fileee => fileToObject(fileee));
return filesl;
}
function fileToObject(filee) {
if (filee.includes("/")) {
// this is a folder
let count = filee.indexOf("/");
return {text: filee.substring(0, count), children: [fileToObject(filee.substring(count + 1))]}
} else {
// this is a file
return {text: filee}
}
}
export default listToTree
it outputs:
[ { text: 'Folder', children: [ { text: 'file.ext' } ] },
{ text: 'Folder', children: [ { text: 'file2.ext' } ] },
{ text: 'Folder', children: [ { text: 'file3.ext' } ] },
{ text: 'Folder',
children:
[ { text: 'nestedfolder', children: [ { text: 'file.ext' } ] } ] },
{ text: 'Folder2', children: [ { text: 'file1.ext' } ] },
{ text: 'Folder2', children: [ { text: 'file2.ext' } ] },
{ text: 'file1.ext' },
{ text: 'file2.ext' },
{ text: 'file3.ext' } ]
now as you can see. each file list array getting its own object. I need to bine the files located in the same folder location.
I need a javascript function to turn an array with file path string to object as follows:
let files = [
"Folder/file.ext",
"Folder/file2.ext",
"Folder/file3.ext",
"Folder/nestedfolder/file.ext",
"Folder2/file1.ext",
"Folder2/file2.ext",
"file1.ext",
"file2.ext",
"file3.ext",
];
listToTree(files);
And It should output an array with an object as follows:
[
{
text: "Folder",
children: [
{text: "file.ext"},
{text: "file1.ext"},
{text: "file2.ext"},
{text: "nestedfolder", children: [{text: "file.ext"}]},
]
},
{
text: "Folder2",
children: [
{text: "file1.ext"},
{text: "file2.ext"},
]
},
{text: "file1.ext"},
{text: "file2.ext"},
{text: "file3.ext"}
];
Here is the current function I am using. but it is not quite there.
function listToTree(files) {
let filestmp = files.map(file => {
if (typeof file === "string") return file;
return file.path
});
let filesl = filestmp.map(fileee => fileToObject(fileee));
return filesl;
}
function fileToObject(filee) {
if (filee.includes("/")) {
// this is a folder
let count = filee.indexOf("/");
return {text: filee.substring(0, count), children: [fileToObject(filee.substring(count + 1))]}
} else {
// this is a file
return {text: filee}
}
}
export default listToTree
it outputs:
[ { text: 'Folder', children: [ { text: 'file.ext' } ] },
{ text: 'Folder', children: [ { text: 'file2.ext' } ] },
{ text: 'Folder', children: [ { text: 'file3.ext' } ] },
{ text: 'Folder',
children:
[ { text: 'nestedfolder', children: [ { text: 'file.ext' } ] } ] },
{ text: 'Folder2', children: [ { text: 'file1.ext' } ] },
{ text: 'Folder2', children: [ { text: 'file2.ext' } ] },
{ text: 'file1.ext' },
{ text: 'file2.ext' },
{ text: 'file3.ext' } ]
now as you can see. each file list array getting its own object. I need to bine the files located in the same folder location.
Share Improve this question edited Oct 31, 2018 at 16:54 Bubun asked Oct 31, 2018 at 15:27 BubunBubun 4567 silver badges18 bronze badges 4- Questions that imply having us write it for you are frowned upon, Take a look at the .split() method of javascript strings, and get to know recursion. Take a shot and ask for help if you run into trouble. – Jim B. Commented Oct 31, 2018 at 15:32
- This is my current code. but it is not quite there, – Bubun Commented Oct 31, 2018 at 15:35
- Great. Can you put your current solution in the question, and describe what's not working? – Jim B. Commented Oct 31, 2018 at 15:42
- already did. check. – Bubun Commented Oct 31, 2018 at 15:45
2 Answers
Reset to default 5Having a tree represented as an array is a little inconvenient because you need to search the array each time to find the appropriate node, which would be inefficient for large arrays. On option is to just build a tree object in one pass and then do a second pass to just take the Object.values
. Here's an example of that:
let files = ["Folder/file.ext","Folder/file2.ext","Folder/file3.ext","Folder/nestedfolder/file.ext","Folder2/file1.ext","Folder2/file2.ext","file1.ext","file2.ext","file3.ext",];
function addPath(arr, obj = {}){
let ponent = arr.shift()
let current = obj[ponent] || (obj[ponent] = {text:ponent})
if (arr.length) {
addPath(arr, current.children || (current.children = {}))
}
return obj
}
function makeArray(obj){
let arr = Object.values(obj)
arr.filter(item => item.children).forEach(item => {
item.children = makeArray(item.children)
})
return arr
}
// make tree
let treeObj = files.reduce((obj, path) => addPath(path.split('/'), obj), {})
// convert to array
let arr = makeArray(treeObj)
console.log(arr)
An alternative is using find()
which will work and may be easier to read…but may be less efficient because you need to search the result array on each pass:
let files = ["Folder/file.ext","Folder/file2.ext","Folder/file3.ext","Folder/nestedfolder/file.ext","Folder2/file1.ext","Folder2/file2.ext","file1.ext","file2.ext","file3.ext",];
function addPath(pathponents, arr ){
let ponent = pathponents.shift()
let p = arr.find(item => item.text === ponent)
if (!p) {
p = {text: ponent}
arr.push(p)
}
if(pathponents.length){
addPath(pathponents, p.children || (p.children = []))
}
return arr
}
let res = files.reduce((arr, path) => addPath(path.split('/'), arr), [])
console.log(res)
Here's my take, one function, no recursion:
const listToTree = files =>
files.map(file => file.split('/'))
.reduce((out, path) => {
let top = out;
while (path.length > 0) {
let node = path.shift();
if (top.findIndex(n => n.text === node) === -1) {
top.push({
text: node
});
}
if (path.length > 0) {
let index = top.findIndex(n => n.text === node);
top[index] = top[index] || {};
top[index].children = top[index].children || [];
top[index].children.push({
text: path[0]
});
top = top[index].children;
}
}
return out;
}, []);
let files = [
'Folder/file.ext',
'Folder/file2.ext',
'Folder/file3.ext',
'Folder/nestedfolder/file.ext',
'Folder2/nestedfolder1/nestedfolder2/file1.ext',
'Folder2/file2.ext',
'file1.ext',
'file2.ext',
'file3.ext'
];
console.log(listToTree(files));
本文标签: javascriptTurn an array with file path to object as mentionedStack Overflow
版权声明:本文标题:javascript - Turn an array with file path to object as mentioned - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742059573a2418498.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论