1

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



                                    }
2
  • "We need to generate..." - You. Not us. So what have you done so far to solve this on your own? And what problems do you have with that approach? Commented Sep 13, 2022 at 10:21
  • @Andreas edited the question please check and give you inputs how you can help Commented Sep 13, 2022 at 10:28

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

11 Comments

The problem with this solution is if incase I have childs with same name with two diffrent parents this won't work [{ L0: "India", L0_ID: "IN", L1: "Karnataka"},{ L0: "Srilanka", L0_ID: "SL", L1: "Karnataka"}]
what goes wrong in this case? the iteration starts from L0 and goes to the largest number.
I think it will work just let me check and get back to you. Thanks a lot. :D
Why (q => q.name === name) and not by id?
@ITgoldman because id can be null
|
0

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])

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.