Android Geek
Android Geek

Reputation: 608

Build Tree Structure of the given flat array

I want to convert the flat array structure to the parent child tree structure upto N levels. The keys L0, L1, L2, L3, L4, L5, L6 are denoted as the the levels and they can go upto max L6. I have some idea about the recursive function but not sure how this can be implemented

Below is the given flat array

[{
  "L0": "India",
  "L0_ID": "IN",
  "L1": "Karnataka",
  "L1_ID": "KA",
  "L2": "BLR",
  "L3": "Mysore",
  "L4": "CHB"
},
{
  "L0": "India",
  "L0_ID": "IN",
  "L1": "Karnataka",
  "L1_ID": "KA",
  "L2": "BLR",
  "L3": "Hubli"
},
{
  "L0": "India",
  "L0_ID": "IN",
  "L1": "Karnataka",
  "L1_ID": "KA",
  "L2": "BLR",
  "L3": "Udupi"
},
{
  "L0": "India",
  "L0_ID": "IN",
  "L1": "Rajasthan",
  "L1_ID": "RJ",
  "L2": "Jaipur",
  "L3": "Shastri Nagar",
  "L4": "Lane One"
},
{
  "L0": "India",
  "L0_ID": "IN",
  "L1": "Rajasthan",
  "L1_ID": "RJ",
  "L2": "Jodhpur",
  "L3": "Shastri Nagar",
  "L4": "Lane One"
}] 

I want generate the desired tree array structure using javascript.

{
  "name": "India",
  "id": "IN",
  "child": [
    {
      "name": "Karnataka",
      "id": "KA",
      "child": [
        {
          "name": "BLR",
          "id": null,
          "child": [
            {
              "name": "Mysore",
              "id": null
            },
            {
              "name": "Hubli",
              "id": null
            },
            {
              "name": "Udupi",
              "id": null
            }
          ]
        }
      ]
    },
    {
      "name": "Rajasthan",
      "id": "RJ"
    }
  ]
}

This is what I have tried so far

 function generate_tree_map(level,data) {
                                     //Get ALL UNIQUE RECORDS AT GIVEN LEVEL
                                       // var unique_records_l0 = _.uniqBy(response, function (e) {
                                        var unique_records_l0 = _.uniqWith(data, function(first, second) {
                                            if (level == 0) {
                                                //console.log("LEVEL ZERO => ", e.L0)
                                                return first.L0 === second.L0 
                                            }
                                            if (level == 1) {
                                                //console.log("LEVEL ONE => ", e.L0, e.L1)
                                                return first.L0 === second.L0 && first.L1 === second.L1
                                            }
                                            if (level == 2) {
                                                //console.log("LEVEL TWO => ", e.L0, e.L1, e.L2)
                                                return first.L0 === second.L0 && first.L1 === second.L1 && first.L2 === second.L2
                                            }
                                            if (level == 3) {
                                                //console.log("LEVEL THREE => ", e.L0, e.L1, e.L2, e.L3)
                                                return first.L0 === second.L0 && first.L1 === second.L1 && first.L2 === second.L2 && first.L3 === second.L3
                                                
                                            }
                                            if (level == 4) {
                                                //console.log("LEVEL FOUR => ", e.L0, e.L1, e.L2, e.L3, e.L4)
                                                return first.L0 === second.L0 && first.L1 === second.L1 && first.L2 === second.L2 && first.L3 === second.L3 && first.L4 === second.L4
                                                
                                            }
                                            if (level == 5) {
                                                //console.log("LEVEL FIVE => ", e.L0, e.L1, e.L2, e.L3, e.L4, e.L5)
                                                return first.L0 === second.L0 && first.L1 === second.L1 && first.L2 === second.L2 && first.L3 === second.L3 && first.L4 === second.L4 && first.L5 === second.L5
                                                
                                            }
                                            //return e[`L${level}`] ;
                                        })

                                        for (let index = 0; index < 6; index++) {
                                            unique_records_l0.forEach(element => {
                                                    var obj = {}
                                                    obj.name = element[`L${level}`]
                                                    obj.id = element[`L${level}_mask`]
                                                    obj.children = []
                                                    if (level < 6) {
                                                        level = level + 1
                                                        obj.children = generate_tree_map(level, response)
                                                    }
                                                    tree.push(obj)
                                                });
                                         }

                                        // var unique_records_l1 = _.uniqBy(data, function (e) {
                                        //     return e[`L${level}`] && e[`L${level+1}`] ;
                                        // })

                                        return unique_records_l0



                                    }

Upvotes: 1

Views: 822

Answers (2)

YJR
YJR

Reputation: 1202

This code will give expected output and it can be extend to any num of levels. For this code first I create a graph using flat array and then create tree using recursion. To use this function You have to know the N level before.

var data_arr = [{
    "L0": "India",
    "L0_ID": "IN",
    "L1": "Karnataka",
    "L1_ID": "KA",
    "L2": "BLR",
    "L3": "Mysore",
    "L4": "CHB"
},
{
    "L0": "India",
    "L0_ID": "IN",
    "L1": "Karnataka",
    "L1_ID": "KA",
    "L2": "BLR",
    "L3": "Hubli"
},
{
    "L0": "India",
    "L0_ID": "IN",
    "L1": "Karnataka",
    "L1_ID": "KA",
    "L2": "BLR",
    "L3": "Udupi"
},
{
    "L0": "India",
    "L0_ID": "IN",
    "L1": "Rajasthan",
    "L1_ID": "RJ",
    "L2": "Jaipur",
    "L3": "Shastri Nagar",
    "L4": "Lane One"
},
{
    "L0": "India",
    "L0_ID": "IN",
    "L1": "Rajasthan",
    "L1_ID": "RJ",
    "L2": "Jodhpur",
    "L3": "Shastri Nagar",
    "L4": "Lane One"
}]

var id_map = {}
function generate_graph(all_data, max_level) {
    var graph = { 'L': [] }
    for (let i = 0; i < all_data.length; i++) {
        var parent = 'L'
        var data = all_data[i]
        for (let j = 0; j < max_level + 1; j++) {
            id_map[data[`L${j}`]]= data[`L${j}_ID`]
            if (!graph.hasOwnProperty(data[`L${j}`])) {
                if (data.hasOwnProperty(`L${j}`)) {
                    graph[data[`L${j}`]] = []
                }
            }
            if (!graph[parent].includes(data[`L${j}`]) && data[`L${j}`]) {
                graph[parent].push(data[`L${j}`])
            }
            parent = data[`L${j}`]
        }
    }
    return graph
}

function generate_tree(current,graph,t){
    for (let k = 0; k <  graph[current].length; k++ ) {
        var node = graph[current][k]
        var tmp={}
        tmp.name = node
        if(id_map[node]){
           tmp.id= id_map[node]
        }
        tmp.child = []
        t.push(tmp)
        generate_tree(node, graph,tmp.child)
    }
}
var max_level =4
var tree=[]

generate_tree('L',generate_graph(data_arr, 4),tree)
console.log(tree[0])

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386560

You could take an iterative approach by finding the wanted name of a given level.

If not found take a new object and take this object for the next level.

const
    data = [{ L0: "India", L0_ID: "IN", L1: "Karnataka", L1_ID: "KA", L2: "BLR", L3: "Mysore", L4: "CHB" }, { L0: "India", L0_ID: "IN", L1: "Karnataka", L1_ID: "KA", L2: "BLR", L3: "Hubli" }, { L0: "India", L0_ID: "IN", L1: "Karnataka", L1_ID: "KA", L2: "BLR", L3: "Udupi" }, { L0: "India", L0_ID: "IN", L1: "Rajasthan", L1_ID: "RJ", L2: "Jaipur", L3: "Shastri Nagar", L4: "Lane One" }, { L0: "India", L0_ID: "IN", L1: "Rajasthan", L1_ID: "RJ", L2: "Jodhpur", L3: "Shastri Nagar", L4: "Lane One" }],
    tree = data.reduce((r, o) => {
        let i = 0,
            t = { children: r };
            
        while (`L${i}` in o) {
            const
                name = o[`L${i}`],
                id = o[`L${i}_ID`] || null;
            let item = (t.children ??= []).find(q => q.name === name);
            if (!item) t.children.push(item = { name, id });
            t = item;
            i++;
        }
        return r;
    }, []);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

Related Questions