2

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)

asked Sep 14, 2022 at 23:42
4
  • What is treeNodeInput = ['0-0-0', '1-0-1'];? Did you define it? Commented Sep 15, 2022 at 0:09
  • I think its the index path to get his data, i.e. for 1-0-1 tree[1], then tree[1].children[0], then tree[1].children[0].children[1] Commented Sep 15, 2022 at 0:17
  • Yes, it is an index path to tree data. Commented Sep 15, 2022 at 0:23
  • @Jason22 - Okay, I wrote my solution without using that treeNodeInput. Commented Sep 15, 2022 at 0:29

3 Answers 3

1

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)

answered Sep 15, 2022 at 0:25
Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

0

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

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.