How to convert newick tree format to tree like Hierarchical javascript object

青春壹個敷衍的年華 提交于 2019-12-23 04:48:21

问题


I am currently studying newick format. https://en.wikipedia.org/wiki/Newick_format I have a newick string of a tree

(A,B,(C,D)E)F;

How to convert this string into a hierarchical javascript object like

tree = {
  name: 'F',
  children: [{
    name: 'A'
  }, {
    name: 'B'
  }, {
    name: 'E',
    children: [{
      name: 'C'
    }, {
      name: 'D'
    }]
  }]

}

回答1:


The code below should work correctly with any input similar to your example.

However, it assumes that each node is identified with a single character. You'd have to modify it to support longer symbols.

Also, this code is not bullet-proof and will break without any warning on invalid input strings.

The main idea is to parse the string in reverse order and keep track of node hierarchy using the stack array.

var newick = '(A,B,(C,D)E)F',
    stack = [],
    child,
    root = [],
    node = root;

newick.split('').reverse().forEach(function(n) {
  switch(n) {
    case ')':
      // ')' => begin child node
      stack.push(node);
      node = child.children = [];
      break;

    case '(':
      // '(' => end of child node
      node = stack.pop();
      break;

    case ',':
      // ',' => separator (ignored)
      break;

    default:
      // assume all other characters are node names
      node.push(child = { name: n });
      break;
  }
});

And here is a simple function that will dump the resulting structure:

var dmp;

(dmp = function(node, level) {
  node.forEach(function(n) {
    console.log(Array(level).join('-') + n.name);
    n.children && dmp(n.children, level + 1);
  });
})(root, 1);

Output:

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



回答2:


You might want to look at taking substrings of the original tree and writing a recursive function that stores the removed letters per heirarchical level.

Possible starter:

var str = "Z,I,(A,B,(C,D)E)F,G,H";

var firstClose = str.indexOf("(");
var lastClose = str.lastIndexOf(")");

console.log(firstClose);
console.log(lastClose);

var remainingTree = str.substr(firstClose , lastClose);
console.log(remainingTree);

var lastLetterStr = (str.substring( lastClose + 1 ) );
var lastLetterArray = lastLetterStr.split(',');

var firstLetterStr = str.substring(0,firstClose-1)
var firstLetterArray = firstLetterStr.split(',')

console.log(lastLetterArray);
console.log(firstLetterArray);

Apply the same steps to the remainingTree string until the string is empty and then create the tree object? You'll have to include some logic so that the function knows how to associate for example (C,D) as children of E when building up the time object

JS Fiddle




回答3:


You can try NewickJS

Example:

var newick = new Newick('(A:0.1,B:0.2,(C:0.3,D:0.4)E:0.5)F');

Or you can use static method:

var tree = Newick.parse('(A:0.1,B:0.2,(C:0.3,D:0.4)E:0.5)F');

The result:

{
    name: "F",
    branchset: [
    {
        name: "A",
        length: 0.1
    },
    {
        name: "B",
        length: 0.2
    },
    {
        name: "E",
        length: 0.5,
        branchset: [
        {
            name: "C",
            length: 0.3
        },
        {
            name: "D",
            length: 0.4
        }]
    }]
}

NewickJS at GitHub



来源:https://stackoverflow.com/questions/38310065/how-to-convert-newick-tree-format-to-tree-like-hierarchical-javascript-object

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!