Issue
I struggle with tree structure. :(
I would like to make a tree following the below interface.
export type Tree = Array<TreeNode>;
export interface TreeNode {
label: string;
type: 'folder' | 'file';
children: Array<TreeNode> | string;
}
For example,
I have a JSON file like this
{
"common.header.title": "Header Title",
"common.footer.btn": "Footer button",
"common.footer.btn.submit": "Footer Submit",
"apage.title": "apage Title"
}
My expected output is like this.
const out = [
{
label: 'apage',
type: 'folder',
children: [
{ label: 'title', type: 'file', children: 'apage Title' }
]
}, {
label: 'common',
type: 'folder',
children: [
{
label: 'footer',
type: 'folder',
children: [
{ label: 'btn', type: 'file', children: 'Footer button' },
{
label: 'btn',
type: 'folder',
children: [{ label: 'submit', type: 'file', children: 'Footer Submit' }]
},
]
}, {
label: 'header',
type: 'folder',
children: [{ label: 'title', type: 'file', children: 'Header Title' }]
}
]
}
]
I've seen some similar cases in SO, but I couldn't refer and develop with that cases.
Solution
You could search for the wanted labels and check if children
is an array, then use this object for searchin in the nested array.
Finally push a new object.
const
data = { "common.header.title": "Header Title", "common.footer.btn": "Footer button", "common.footer.btn.submit": "Footer Submit", "apage.title": "apage Title" },
result = Object
.entries(data)
.sort(([a], [b]) => a.localeCompare(b))
.reduce((r, [path, children]) => {
const
keys = path.split('.'),
label = keys.pop();
keys
.reduce((t, label) => {
let temp = t.find(o => o.label === label && Array.isArray(o.children));
if (!temp) t.push(temp = { label, type: 'folder', children: [] });
return temp.children;
}, r)
.push({ label, type: 'file', children });
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Answered By - Nina Scholz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.