I need to create a flat array using various hierarchical tree data. I'll get array of tree nodes as string in the form of parentNode-childNode-... This is all dynamic. I tried to convert treeNodeInput into nested object, but couldn't make use of that.
const TREE_DATA = [{
name: 'USA',
children: [{
name: 'Texas',
children: [{
name: 'Dallas'
}, {
name: 'Houston'
}]
}, {
name: 'California',
children: [{
name: 'Los Angeles'
}, {
name: 'San Francisco'
}]
}, {
name: 'New York',
children: [{
name: 'New York City'
}, {
name: 'Buffalo'
}]
}],
}, {
name: 'India',
children: [{
name: 'Bihar',
children: [{
name: 'Patna'
}, {
name: 'Gaya'
}],
}],
}, ];
let treeDataGroupedBy = ['Country', 'State', 'City'];
let treeNodeInput = ['0-0-0', '1-0-1'];
let data = []; /*Expected Result [{
Country: 'USA',
State: 'Texas',
City: 'Dallas'
}, {
Country: 'India',
State: 'Bihar',
City: 'Gaya'
}]*/
for (let item of treeNodeInput) {
let nodesArray = item.split("-");
let count = 0;
let rowObj = {};
for (let node of nodesArray) {
rowObj[treeDataGroupedBy[count]] = Object.keys(TREE_DATA)[Number(node)];
count++;
}
data.push(rowObj);
}
console.log(data)
3 Answers 3
You can get expected result by doing this minimum code change.
const TREE_DATA = [{
name: 'USA',
children: [{
name: 'Texas',
children: [{
name: 'Dallas'
}, {
name: 'Houston'
}]
}, {
name: 'California',
children: [{
name: 'Los Angeles'
}, {
name: 'San Francisco'
}]
}, {
name: 'New York',
children: [{
name: 'New York City'
}, {
name: 'Buffalo'
}]
}],
}, {
name: 'India',
children: [{
name: 'Bihar',
children: [{
name: 'Patna'
}, {
name: 'Gaya'
}],
}],
}, ];
let treeDataGroupedBy = ['Country', 'State', 'City'];
let treeNodeInput = ['0-0-0', '1-0-1'];
let data = []; /*Expected Result [{
Country: 'USA',
State: 'Texas',
City: 'Dallas'
}, {
Country: 'India',
State: 'Bihar',
City: 'Gaya'
}]*/
for (let item of treeNodeInput) {
let nodesArray = item.split("-");
let count = 0;
let rowObj = {};
let child = TREE_DATA
for (let node of nodesArray) {
if(child.hasOwnProperty('children')){
child =child["children"][node]
}
else{
child =child[node]
}
rowObj[treeDataGroupedBy[count]] = child.name;
count++;
}
data.push(rowObj);
}
console.log(data)
Sign up to request clarification or add additional context in comments.
Comments
You can do this reccursively:
const TREE_DATA = [{
name: 'USA',
children: [{
name: 'Texas',
children: [{
name: 'Dallas'
}, {
name: 'Houston'
}]
}, {
name: 'California',
children: [{
name: 'Los Angeles'
}, {
name: 'San Francisco'
}]
}, {
name: 'New York',
children: [{
name: 'New York City'
}, {
name: 'Buffalo'
}]
}],
}, {
name: 'India',
children: [{
name: 'Bihar',
children: [{
name: 'Patna'
}, {
name: 'Gaya'
}],
}],
}, ];
let treeDataGroupedBy = ['Country', 'State', 'City'];
let treeNodeInput = ['0-0-0', '1-0-1'];
let data = [];
function LinearifyTree(tree, keys, path) {
let val = {keys[0]: tree[path[0]].name};
if (key.length === 1) {
return val;
}
return {...val, ...LinearifyTree(tree[path[0]].children, keys.slice(1), path.slice(1))};
}
for (let item of treeNodeInput) {
let nodeArray = item.split('-').map(v => Number(v));
data = LinearifyTree(TREE_DATA, treeDataGroupedBy, nodeArray);
}
console.log(data);
Is it optimal? No Will it work? yes Do you want it to be optimal? Change your data structure
answered Sep 15, 2022 at 0:14
michmich112
7744 silver badges8 bronze badges
Comments
Here is a recursive function to build that desired result.
const TREE_DATA=[{name:'USA',children:[{name:'Texas',children:[{name:'Dallas'},{name:'Houston'}]},{name:'California',children:[{name:'LosAngeles'},{name:'SanFrancisco'}]},{name:'NewYork',children:[{name:'NewYorkCity'},{name:'Buffalo'}]}],},{name:'India',children:[{name:'Bihar',children:[{name:'Patna'},{name:'Gaya'}],}],},];
let treeDataGroupedBy = ['Country', 'State', 'City'];
let result = [];
for (const data of TREE_DATA) {
buildResult(data, treeDataGroupedBy, 0, {}, result);
}
console.log(result);
function buildResult(data, treeDataGroupedBy, level, obj, result) {
if (!data || level >= treeDataGroupedBy.length) {
return;
}
const name = treeDataGroupedBy[level]; // 'Country', 'State', or 'City'
obj[name] = data.name;
if (!data.children) {
// No children exists, so no more levels down, so push the object to the result and return.
result.push(obj);
return;
}
for (let child of data.children) {
// Children exists, so visit each child. Increment level and pass object copy.
buildResult(child, treeDataGroupedBy, level + 1, {...obj}, result);
}
}
answered Sep 15, 2022 at 0:21
Nikhil
6,68110 gold badges36 silver badges74 bronze badges
Comments
lang-js
treeNodeInput = ['0-0-0', '1-0-1'];? Did you define it?tree[1], thentree[1].children[0], thentree[1].children[0].children[1]treeNodeInput.