1

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

user21
  • 1,261
  • 5
  • 20
  • 41
  • Please update your question and clarify what the problem is that you're experiencing. You've told us what you're trying to do, but it's not clear what the problem is. – devlin carnate May 29 '18 at 22:38
  • There are rather a few problems here, what do you think `new Node(string)` does in Javascript? Also were are you checking that you haven't already added a the node. eg. transportation is listed 7 times, but you only want 1 node, here your adding nodes regardless. – Keith May 29 '18 at 22:48
  • In JS, since it does not has new Node method, maybe i should replace it with var root = "". I could add a function to check whether the parent node exists or not. – user21 May 29 '18 at 22:59

2 Answers2

1

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

Eddie D
  • 1,120
  • 7
  • 16
1

You can do it, with a data structure as Tree, you only need loop over the array of string that contains the data and split them by dot and then add each item to the tree instance that will be created when you execute the function that take your array and output as a Tree data structure.

this code can help you

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

function Node(data) {
 this.data = data;
 this.children = [];
}

function Tree(data) {
 this.root = null;
}

Tree.prototype.contains = function(data) {
 return this.find(data) ? true : false;
}

Tree.prototype.add = function(data, node) {
 const newNode = new Node(data);

 if (!this.root) {
  this.root = newNode;
  return;
 }

 const parent = node ? this.find(node) : null;
 
 if (parent) {
  if (!this.contains(data)) {
    parent.children.push(newNode);
  }
 }
}

Tree.prototype.find = function(data) {
 if (this.root) {
  const queue = [this.root];
  while(queue.length) {
   const node = queue.shift();
   if (node && node.data === data) {
    return node;
   }

   for(var i = 0; i < node.children.length; i++) {
    const child = node.children[i];
    queue.push(child);
   }
  }
 }
 return null;
}

function createTreeOfTransportation(arr) {
 const tree = new Tree();
 for(var i = 0; i < arr.length; i++) {
  const element = arr[i];
  const nodes = element.split('.');

  for (var j = 0; j < nodes.length; j++) {
   const currentNode = nodes[j];
   const parent = nodes[j-1];
   console.log(j, parent);
   tree.add(currentNode, parent);
  }
 }
 
 return tree;
}

console.log(createTreeOfTransportation(arr));
Juorder Gonzalez
  • 1,642
  • 1
  • 8
  • 10