I'm looking to try and concatenate the array down to the base folder hierarchy.
In my example below "Level 1" is the lowest level there are no children folders to this level. The "other level" will have a multitude of different folders all under the "Top Level"
The array I have the data is as follows:
[{ id: "Top Level", outerpath: "test plan", innerpath: "Regression" },
{ id: "other level", outerpath: "Regression", innerpath: "area 1" },
{ id: "Level 1", outerpath: "area 1", innerpath: "Subarea 1" },
{ id: "Level 1", outerpath: "area 1", innerpath: "Subarea 2" },
{ id: "Level 1", outerpath: "Regression", innerpath: "area 2" }]
Now I needing the results of the concaternation of the data within the object array to look like this:
test plan/Regression/area 1/Subarea 1
test plan/Regression/area 1/Subarea 2
test plan/Regression/area 2
However I have no clue how to start this. Perhaps its along the lines of a loop through the array matching "innerpath" and "outpath" values then pushing the completed data to another array?
Any ideas would be really useful.
UPDATE:
To expand on my question the array is dynamic and depending of the results of the API it might be like this array
[{ id: "Top Level", outerpath: "test plan", innerpath: "Regression" }
{ id: "other level", outerpath: "Regression", innerpath: "area 1" }
{ id: "Level 1", outerpath: "area 1", innerpath: "Subarea 1" }
{ id: "other level", outerpath: "area 1", innerpath: "Subarea 2" }
{ id: "Level 1", outerpath: "Regression", innerpath: "area 2" }
{ id: "Top Level", outerpath: "test plan", innerpath: "other testing" }
{ id: "Level 1", outerpath: "other testing", innerpath: "other testing area 1" }
{ id: "other level", outerpath: "other testing", innerpath: "other testing area 2" }
{ id: "Level 1", outerpath: "other testing area 2", innerpath: "other testing subarea 1" }
{ id: "Level 1", outerpath: "Subarea 2", innerpath: "SubSubArea 1" }]
So there isn't going to be just one top level it could be multiple top levels as the folder "test plan" will have multiple folders with some of them with subfolders of their own.
My code that collated the data from the callback from the API call is here:
let testSuiteData = res;
testSuiteData.value.forEach(async testSuiteItem => {
console.log(testSuiteItem);
if(!testSuiteItem.hasChildren === true) // Level 1
{
console.log(testSuiteItem.parentSuite.name + '/' + testSuiteItem.name)
folderHierarchy.path.push({
id: 'Level 1',
outerpath: testSuiteItem.parentSuite.name,
innerpath: testSuiteItem.name
})
}
else if(testSuiteItem.hasChildren === true ) // other levels
{
if(testSuiteItem.parentSuite.name === testSuiteItem.plan.name) // Top Level
{
console.log(testSuiteItem.parentSuite.name + '/' + testSuiteItem.name)
folderHierarchy.path.push({
id: 'Top Level',
outerpath: testSuiteItem.parentSuite.name,
innerpath: testSuiteItem.name
})
}
else{ // Other Levels
console.log(testSuiteItem.parentSuite.name + '/' + testSuiteItem.name)
folderHierarchy.path.push({
id: 'other level',
outerpath: testSuiteItem.parentSuite.name,
innerpath: testSuiteItem.name
})
}
}
console.log(folderHierarchy.path);
You could do something like this
const array = [{ id: "Top Level", outerpath: "test plan", innerpath: "Regression" }, { id: "other level", outerpath: "Regression", innerpath: "area 1" }, { id: "Level 1", outerpath: "area 1", innerpath: "Subarea 1" }, { id: "Level 1", outerpath: "area 1", innerpath: "Subarea 2" }, { id: "Level 1", outerpath: "Regression", innerpath: "area 2" }] const obj = {}; // a map of all our paths const topLevel = array.splice(0, 1)[0]; // removing the top level from array as it is not needed, and for further reference const base = `${topLevel.outerpath}/${topLevel.innerpath}`; // creating our default path, which we will use as a reference later for (let i = 0; i < array.length; i++) { const path = array[i].outerpath.split(' '); // creating a unique key for our map const key = path[1] ? path[1] : path[0]; if (!obj[key]) obj[key] = []; if (path[0] == 'area') obj[key].push(`${base}/${array[i].outerpath}/${array[i].innerpath}`); else if (path[0] == 'Regression') obj[key].push(`${base}/${array[i].innerpath}`) } console.log(obj);
My approach in steps:
Try to do it yourself and only then check this example on how it can be achieved.
class TreeList { tree = null; isTopLevel = (level) => { let topLevel = true; this.data.map(lv => { if (lv.innerPath === level.outerPath) { topLevel = false; } }); return topLevel; } createTree = (data) => { this.data = data; data.map(level => { if (this.isTopLevel(level)) { this.tree = level; } }); if (this.tree === null) { console.error('Couldn\\'t find top level.'); return; } this.tree = this.findChildLevels(this.tree); return this.flattenObject(this.tree); } findChildLevels = (level) => { this.data.map(lv => { if (lv.outerPath === level.innerPath) { if (level?.children === null || level?.children === undefined) { level.children = []; } level.children.push(this.findChildLevels(lv)); } }); return level; } flattenObject = (level) => { let currentPath = level.outerPath; let list = []; if (level?.children !== undefined && level?.children !== null) { level.children.map(child => { this.flattenChildren(list, currentPath, child); }); } else { list = [currentPath]; } return list } flattenChildren = (list, currentPath, level) => { if (level?.children !== undefined && level?.children !== null) { // currentPath += `/${level.outerPath}`; currentPath += '/' + level.outerPath; level.children.map(child => { this.flattenChildren(list, currentPath, child) }); } else { // list.push(`${currentPath}/${level.outerPath}/${level.innerPath}`); list.push(currentPath + '/' + level.outerPath + '/' + level.innerPath); } return list; } } const tl = new TreeList() const list = tl.createTree([ {id: "Top Level", outerPath: "test plan", innerPath: "Regression"}, {id: "other level", outerPath: "Regression", innerPath: "area 1"}, {id: "Level 1", outerPath: "area 1", innerPath: "Subarea 1"}, {id: "Level 1", outerPath: "area 1", innerPath: "Subarea 2"}, {id: "Level 1", outerPath: "Regression", innerPath: "area 2"} ]); list.map(item => { console.log(item); });
I think we can simplify this a bit more by first creating a list of all unique innerpath
values which do not also appear as outerpath
values and then traversing backwards from each.
Here's how that would look, using your latest dynamic array of objects:
I excluded the
id
property values from your original data, as it did not appear to be getting used anywhere, just for the sake of keeping this example concise, but you can certainly add that back in your final version.
const data = [ { outerpath: "test plan", innerpath: "Regression" }, { outerpath: "Regression", innerpath: "area 1" }, { outerpath: "area 1", innerpath: "Subarea 1" }, { outerpath: "area 1", innerpath: "Subarea 2" }, { outerpath: "Regression", innerpath: "area 2" }, { outerpath: "test plan", innerpath: "other testing" }, { outerpath: "other testing", innerpath: "other testing area 1" }, { outerpath: "other testing", innerpath: "other testing area 2" }, { outerpath: "other testing area 2", innerpath: "other testing subarea 1" }, { outerpath: "Subarea 2", innerpath: "SubSubArea 1" } ]; const outerpaths = data.map(({ outerpath }) => outerpath), innerpaths = data.map(({ innerpath }) => innerpath).filter(innerpath => !outerpaths.includes(innerpath)); const concatenated = innerpaths.map(innerpath => { let obj = data.find(obj => obj.innerpath === innerpath), str = obj.outerpath + '/' + innerpath, i = 0; do { obj = data.find(({ innerpath }) => obj.outerpath === innerpath); if (obj) str = obj.outerpath + '/' + str; i++; } while (i < 20 && obj) return str; }); console.log(concatenated.join('\\n'));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.