如何将newick树格式转换为像分层javascript对象这样的树

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

本文关键字:对象 分层 javascript newick 格式 转换      更新时间:2023-09-26

我目前正在研究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'
    }]
  }]
}

下面的代码应该可以与类似于您的示例的任何输入一起正常工作。

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

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

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

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

您可能希望查看获取原始树的子字符串并编写一个递归函数,该函数按层次结构级别存储已删除的字母。

可能的启动器:

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对象? 您必须包含一些逻辑,以便函数知道如何在构建time对象时将(C,D)关联为E的子对象

JS小提琴

你可以试试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