I'm fairly new to typescript and I have some issues to access an object in array with dynamic depth. For example:
export interface folder{
name: string,
type: string,
position: number[], // index for each depth level
children: folder[]
{
"name": "Folder1",
"depth": 0,
"position": [0] // indeces for each depth level
"children": [
{
"name": "Folder2",
"depth": 1,
"position": [0,0] // indeces for each depth level
"children": [
{
"name": "Folder3"
"depth": 2,
"position": [0,0,0] // indeces for each depth level
},
{
"name": "Folder4"
"depth": 2,
"position": [0,0,1] // indeces for each depth level
}
]
}
]
}
To get Folder4 I'd use the dot notation like:
this.folder[0].children[0].children[1]
Now I was wondering, if there is a way to dynamicly access the object via the position array without iterating over the whole structure. I managed to get it working by defining a string and adding ".children[PositionIndex]"
for each value in position and executing it with eval
. However that is obviously not a reasonable/safe way to do this.
Any help would be greatly apprecieated.Thanks!
CodePudding user response:
Instead of having a "position" field that describes the path to a certain depth/folder nested deeply into the structure itself, have a second, shallow structure that maps folder names to depths and use it to reach a folder:
const folders = {
"name": "Folder1",
"depth": 0,
"position": [0], // note: this is wrong, folder one isn't nested and therefor has a position of []
"children": [
{
"name": "Folder2",
"depth": 1,
"position": [0,0],
"children": [
{
"name": "Folder3",
"depth": 2,
"position": [0,0,0]
},
{
"name": "Folder4",
"depth": 2,
"position": [0,0,1]
}
]
}
]
};
const folderDepths = {
// this maps depths to folders. note that "folder1" does not have a
// depth, because it is the root node and is not nested. this means
// that all nodes nested below folder1 have one path segment less
// compared to your original structure.
Folder1: [],
Folder2: [0],
Folder3: [0, 0],
Folder4: [0, 1]
};
const accessFolder = (name, depths, tree) => {
// we use this function to access (sub-)folders. it takes the name
// of the folder to reach, the depths-mapping and the original
// structure. stops when there are no more children to dig into or
// the final depth is reached. returns the accessed (sub-)tree.
let retv = tree;
let path = depths[name];
for (let i = 0; i < path.length && retv; i = 1) {
if (retv.children && retv.children[path[i]]) {
retv = retv.children[path[i]];
}
}
return retv;
}
console.log(accessFolder('Folder2', folderDepths, folders));
console.log(accessFolder('Folder4', folderDepths, folders));