Search code examples
javascriptarraystreeparentnodechildren

given an array representing a hierachy, output data into a tree form in JS


Given a data file which has an array representing a hierarchy. Create a tree data structure by writing a script in Javascript. Output the data in tree form:

Data file:

["transportation.cars.Mazda",
 "transportation.cars.Honda",
 "transportation.cars.Toyota",
 "transportation.train.lightRail",
 "transportation.train.rapidTransit",
 "transportation.waterVehicle.ferry",
 "transportation.waterVehicle.boats" 
 ...]

Output in tree form:

 root
  transportation
    cars
      Mazda
      Honda
      Toyota
    train 
      lightRail
      rapidTransit
    waterVehicle
      ferry
      boats 

My attempt:

var root = new Node('root'); 

var arr = ["transportation.cars.Mazda",
 "transportation.cars.Honda",
 "transportation.cars.Toyota",
 "transportation.train.lightRail",
 "transportation.train.rapidTransit",
 "transportation.waterVehicle.ferry",
 "transportation.waterVehicle.boats" 
 ]

for(var i of arr){
   var res=i.split(".");
    root.addChild(new Node(res[0]));
    res[0].addChild(new Node(res[1])); 
    res[1].addChild(new Node(res[2])); 
 }

this.addChild = function(node) {
    node.setParentNode(this);
    this.children[this.children.length] = node;
} 
console.log(root);

I am trying to create a tree structure using JavaScript, but it does not has the same function as in Java (i.e. it does not have class method unless using Typescript. )


Solution

  • You can use something similar to a trie tree. The way you add a node would have to be much more specific. But it's possible with something like this.

    function Node(word)
    {
      this.value = word;
      this.children = {};
    }
    
    function AddDotChain(chain)
    {
      let arr = chain.split('.');
      let currentNode = this;
    
      function recurse(currentIndex)
      {
        if(currentIndex === arr.length)
        {
          return;
        }
    
        let currentWord = arr[currentIndex];
        if(currentNode.children[currentWord])
        {
          currentNode = currentNode[currentWord];
          return recurse(currentIndex + 1);
        }
    
        let child = new Node(currentWord);
        currentNode.children[currentWord] = child;
        currentNode = child;
        return recurse(currentIndex + 1);
      }
    }

    Where you just slap the entire chain in there without splitting it. There's probably a flaw in my logic somewhere but the overall idea should work. This can also be done iteritavely if you wanna reduce the overhead of recursion. Forgive the messiness, Tried to type this as fast as possible.

    Here's a sloppy sloppy implementation on repl.it. enter image description here