如何将newick树格式转换为像Hierarchical javascript对象一样的树

时间:2016-07-11 14:54:25

标签: javascript logic

我正在研究newick格式。 https://en.wikipedia.org/wiki/Newick_format 我有一个树的新词串

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

如何将此字符串转换为像

这样的分层javascript对象
tree = {
  name: 'F',
  children: [{
    name: 'A'
  }, {
    name: 'B'
  }, {
    name: 'E',
    children: [{
      name: 'C'
    }, {
      name: 'D'
    }]
  }]

}

3 个答案:

答案 0 :(得分:0)

您可能希望查看原始树的子字符串并编写一个递归函数来存储每个层次结构中已删除的字母。

可能的首发:

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

remainingTree字符串应用相同的步骤,直到字符串为空,然后创建tree对象?在构建(C,D)对象时,您必须包含一些逻辑,以便函数知道如何将E作为time的子项进行关联

JS Fiddle

答案 1 :(得分:0)

以下代码可以正常使用与您的示例类似的任何输入。

但是,它假定每个节点都用一个字符标识。您必须修改它以支持更长的符号。

此外,此代码不是防弹的,并且在无效的输入字符串上没有任何警告时会中断。

主要思想是以相反的顺序解析字符串,并使用堆栈数组跟踪节点层次结构。

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;
  }
});

这是一个简单的函数,它将转储结果结构:

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

输出:

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

答案 2 :(得分:0)

您可以尝试NewickJS

示例:

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

或者您可以使用静态方法:

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

结果:

{
    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