简体   繁体   中英

How to convert parent child array to json tree structure by javascript

I have an array of objects which want to convert it to JSON tree structure by java script function and then use it in a vue js project. The page have a vuetify tree component which need JSON tree structure. My data have been stored in MySql table with parent child structure.

Sample Date :

[
    {"id": 123, "parentid": 0, "name": "Mammals"},
    {"id": 456, "parentid": 123, "name": "Dogs"},
    {"id": 214, "parentid": 456, "name": "Labradors"},
    {"id": 810, "parentid": 456, "name": "Pugs"},
    {"id": 919, "parentid": 456, "name": "Terriers"}
]

Result :

[
    {
        "id": 123,
        "parentid": 0,
        "name": "Mammals",
        "children": [
            {
                "id": 456,
                "parentid": 123,
                "name": "Dogs",
                "children": [
                    {
                        "id": 214,
                        "parentid": 456,
                        "name": "Labradors"
                    },
                    {
                        "id": 810,
                        "parentid": 456,
                        "name": "Pugs"
                    },
                    {
                        "id": 919,
                        "parentid": 456,
                        "name": "Terriers"
                    }
                ]
            }
        ]
    }
]

Sample data from this address: https://gist.github.com/smrchy/7040377

You can perform a reduce operation on the array using an object to store the references to each object (for adding children to) and an array to store the result.

 const arr = [ {"id": 123, "parentid": 0, "name": "Mammals"}, {"id": 456, "parentid": 123, "name": "Dogs"}, {"id": 214, "parentid": 456, "name": "Labradors"}, {"id": 810, "parentid": 456, "name": "Pugs"}, {"id": 919, "parentid": 456, "name": "Terriers"} ]; const {res} = arr.reduce((acc,curr)=>{ if(acc.parentMap[curr.parentid]){ (acc.parentMap[curr.parentid].children = acc.parentMap[curr.parentid].children || []).push(curr); } else { acc.res.push(curr); } acc.parentMap[curr.id] = curr; return acc; }, {parentMap: {}, res: []}); console.log(res);

@unmitigated 's response only works if your list is pre-ordered.

Instead, inspired heavily from @alexandru.pausan in Build tree array from flat array in javascript .

I find it easier to understand to:

  • create an object/dictionary of all possible ids in the array, and
  • then go through the dictionary once attaching children to parents:
  const array = [
      { id: 919, parentid: 456, name: "Terriers" },
      { id: 456, parentid: 123, name: "Dogs" },
      { id: 214, parentid: 456, name: "Labradors" },
      { id: 810, parentid: 456, name: "Pugs" },
      { id: 123, parentid: 0, name: "Mammals" },
    ];
    
    let tree = [], arrayDictionary = {};
    
    // First map the nodes of the array to an object/dictionary where the key is their id
    array.forEach((cat) => {
      arrayDictionary[cat.id] = cat;
      arrayDictionary[cat.id]["children"] = [];
    });
    
    
    // for each entry in the dictionary
    for (var entry in arrayDictionary) {

      // get all the data for this entry in the dictionary
      const mappedElem = arrayDictionary[entry];

      // if the element has a parent, add it
      if (
        mappedElem.parentid && // the dictionary has a parent
        arrayDictionary[mappedElem["parentid"]] // and that parent exists
        ) {

        arrayDictionary[mappedElem["parentid"]]["children"].push(mappedElem);
      }
      // else is at the root level (parentid = null or 0)
      else {
        tree.push(mappedElem);
      }
    }
    
    console.log(tree);

 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM