3

I'm trying to create tree from a list . My data is like ;

A-->B-->C-->D-->E..
A-->B-->C-->D-->F..
A-->F-->C-->D-->E..
.
.
.

I have all possible data path in array.I want to show this like

                     A
                       -B
                         -C
                           -D 
                              -E
                              -F
                       -F
                         -C
                           -D
                             -E 

How can i create and check with javascript ? I need createTreeFunction :)

function parseData(data)
  {


   $.each(data, function (i, p) {
                   var arr = p.split("--->");

                 createTreeFunction(p);

                  });

   };
  function parseData(data)
      {


       $.each(data, function (i, p) {
                       var arr = p.split("--->");

                     createTreeFunction(p);

                      });

   };
2
  • 2
    Javascript != Java, and it says that in countless places on this website. Commented May 20, 2016 at 15:55
  • please supply some data which are not invalid (tree wise), or create a loop. please use unique identifier. Commented May 20, 2016 at 16:29

2 Answers 2

3

Basically you can use at least two different structures for the children for building a tree, one with an array (Solution A) or with an object (Solution B).

The advantage of an array over an object is the direct iteration over the children. With an object, you need to get the keys first and then is an iteration possible.

Otherwise if you know one child, then the access over the key is faster. This is also true for inserting new nodes to the tree.

With a children array you need a function getChild for testing if a child is present.

A note, the supplied data does not keep the identifier unique.

Solution A with arrays for children:

function Node(id) {
    this.id = id;
    this.children = []; // array
}

Node.prototype.getChild = function (id) {
    var node;
    this.children.some(function (n) {
        if (n.id === id) {
            node = n;
            return true;
        }
    });
    return node;
};

var path = ['A-->B-->C-->D-->E', 'A-->B-->C-->D-->F', 'A-->F-->C-->D-->E'],
    tree = new Node('root');

path.forEach(function (a) {
    var parts = a.split('-->');
    parts.reduce(function (r, b) {
        var node = r.getChild(b);
        if (!node) {
            node = new Node(b);
            r.children.push(node);
        }
        return node;
    }, tree);
});

document.getElementById('out').innerHTML = JSON.stringify(tree, 0, 4);
<pre id="out"></pre>

Solution B with objects for children:

function Node(id) {
    this.id = id;
    this.children = {}; // object
}

var path = ['A-->B-->C-->D-->E', 'A-->B-->C-->D-->F', 'A-->F-->C-->D-->E'],
    tree = new Node('root');

path.forEach(function (a) {
    var parts = a.split('-->');
    parts.reduce(function (r, b) {
        if (!r.children[b]) {
            r.children[b] = new Node(b);
        }
        return r.children[b];
    }, tree);
});

document.getElementById('out').innerHTML = JSON.stringify(tree, 0, 4);
<pre id="out"></pre>

Both proposals uses Array#forEach and Array#reduce for iterating the given strings and for returning the reference to the actual id. If an id is not found, a new instance of node is taken and added to the array or object. The reference is returned for the next id check.

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

2 Comments

I see that you are not satisfied with the console.log() and started using a cooler display method for the nested thingys. (+) for your solutions.
@Redu, yes, the area is to small to show bigger data structure.
0

For this use cases i had invented very useful two Object methods; namely Object.prototype.getNestedValue() and Object.prototype.setNestedValue(). By utilizing these methods this job is nothing more than a single liner JS code. See below...

Object.prototype.getNestedValue = function(...a) {
  return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};
Object.prototype.setNestedValue = function(...a) {
  return a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1))
                                                                              : (this[a[0]] = typeof a[1] === "string" ? {} : new Array(a[1]),
                                                                                 this[a[0]].setNestedValue(...a.slice(1)))
                      : this[a[0]] = a[1];
};

var data = "A-->B-->C-->D-->E\nA-->B-->C-->D-->F\nA-->F-->C-->D-->E",
  datarr = data.split("\n").map(e => e.split("-->")), // get your list in an array
       o = {};
datarr.forEach(a => !o.getNestedValue(...a) && o.setNestedValue(...a,null));

console.log(JSON.stringify(o,null,2));

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.