简体   繁体   中英

Algorithm to convert a table data to hierarchical tree data using Javascript ECMAScript 6

I have a JSON table data and want to convert to JSON tree data as shown below. I'm looking for an efficient algorithm in JavaScript using any new ECMAScript 6 operator or statements with a functional approach (not by standard recursive algorithm with ES5)?

Table data:

[
   {
      "Children":"4th Grand Father"
   },
   {
      "Name":"4th Grand Father",
      "Children":"3rd Grand Father"
   },
   {
      "Name":"3rd Grand Father",
      "Children":"2nd Grand Father"
   },
   {
      "Name":"2nd Grand Father",
      "Children":"Grand Father"
   },
   {
      "Name":"Grand Father",
      "Children":"Father"
   },
   {
      "Name":"Grand Father",
      "Children":"Uncle"
   },
   {
      "Name":"Uncle",
      "Children":"Cousin"
   },
   {
      "Name":"Father",
      "Children":"Brother"
   },
   {
      "Name":"Father",
      "Children":"Me"
   }
]

Tree data:

[
  {
    "Name": "4th Grand Father",
    "Children": [
      {
        "Name": "3rd Grand Father",
        "Children": [
          {
            "Name": "2nd Grand Father",
            "Children": [
              {
                "Name": "Grand Father",
                "Children": [
                  {
                    "Name": "Father",
                    "children": [
                      {
                        "Name": "Brother"
                      },
                      {
                        "Name": "Me"
                      }
                    ]
                  },
                  {
                    "Name": "Uncle",
                    "children": [
                      {
                        "Name": "Cousin"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]

You could use this ES6 function, which uses a Map , arrow functions, destructured argument assignment. You could even replace the concat call by spread syntax, but I don't think that brings any benefit:

 const makeTree = (data) => { const hash = data.reduce ( (acc, {Name, Children}) => acc.set(Name, (acc.get(Name) || []).concat(Children)) , new Map ); const recurse = (Name) => hash.has(Name) ? { Name, Children: hash.get(Name).map(recurse) } : { Name }; return recurse(undefined).Children; } // Sample data const data = [ { "Children":"4th Grand Father" }, { "Name":"4th Grand Father", "Children":"3rd Grand Father" }, { "Name":"3rd Grand Father", "Children":"2nd Grand Father" }, { "Name":"2nd Grand Father", "Children":"Grand Father" }, { "Name":"Grand Father", "Children":"Father" }, { "Name":"Grand Father", "Children":"Uncle" }, { "Name":"Uncle", "Children":"Cousin" }, { "Name":"Father", "Children":"Brother" }, { "Name":"Father", "Children":"Me" } ]; const result = makeTree(data); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Explanation:

The hash variable is built from an empty Map , adding the records to it keyed by Name . The value linked to each key is the children information, as an array. When the same Name is encountered (ie acc.get(Name) returns something), the child is added to the already existing array, otherwise ( || [] ) an empty array is created and the child is added to that.

Once the hash is complete, the top of the hierarchy is taken by its missing Name ( undefined ), and through recursion the children are looked up in the hash and added to the final object.

As the result object is an object with a Children array, and the desired outcome was in fact that array, it is the Children property that gets returned.

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