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)

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)

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

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);
  }
}

Comments

Your Answer

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.