Javascript 使用json节点和链接生成树层次结构

Javascript 使用json节点和链接生成树层次结构,javascript,arrays,json,d3.js,Javascript,Arrays,Json,D3.js,我想要一个javascript函数,它可以转换节点并将json链接到树json 以下是JSON的节点和链接: { "nodes": [ {name: "Top Level", group: 1}, {name: "Level 2: A", group: 1}, {name: "Son of A", group: 1}, {name: "Daughter of A", group: 1},

我想要一个javascript函数,它可以转换节点并将json链接到树json

以下是JSON的节点和链接:

    {
      "nodes": [
         {name: "Top Level", group: 1},
         {name: "Level 2: A", group: 1},
         {name: "Son of A", group: 1},
         {name: "Daughter of A", group: 1},
         {name: "Level 2: B", group: 1}
      ],
      "links": [
         {source: 0, target: 1, value: 1},
         {source: 0, target: 4, value: 1},
         {source: 1, target: 2, value: 1},
         {source: 1, target: 3, value: 1}
      ]
   }
这里链接的数组中有“源”和“目标”是节点数组索引。 例如{source:0target:1,value:1}:-source:0表示节点[0],而target:1表示节点[1]

转换上述json后,树层次结构如下所示:

[
  {
    "name": "Top Level",
    "parent": "null",
    "children": [
      {
        "name": "Level 2: A",
        "parent": "Top Level",
        "children": [
          {
            "name": "Son of A",
            "parent": "Level 2: A"
          },
          {
            "name": "Daughter of A",
            "parent": "Level 2: A"
          }
        ]
      },
      {
        "name": "Level 2: B",
        "parent": "Top Level"
      }
    ]
  }
];

谢谢。

一个简单的解决方案如下:

var data; // parse the JSON into here
var buildNode = function(index) {

    var children = data.links.filter(function(x) {
        return x.source === index;
    }).map(function(x) {
        return buildNode(x.target);
    });

    //with ES6 you can use .find to get the first matching item, instead of .filter and [0]
    var parent = data.links.filter(function(x) {
        return x.target === index;
    })[0];
    var parentName = parent ? parent.name : undefined;

    return {
        name: data.nodes[index].name,
        parent: parentName,
        children: children
    };
};

var tree = buildNode(0);

注意。首先生成具有相应目标和父级的数组可能更有效,而不是每次遍历整个数组:

var data; // parse the JSON into here
var nodeTargets = [];
var nodeParents = [];
data.links.forEach(function(x) {
    if (!nodeTargets[x.source]) {
        nodeTargets[x.source] = []
    }
    nodeTargets[x.source].push(x.target);

    nodeParents[x.target] = x.source;
});
这将在
nodeTargets
中产生以下数组结构:

[
    [1, 4],
    [2, 3]
]
{
    1: 0,
    4: 0,
    2: 1,
    3: 1
}
以及
nodeParents
中的以下内容:

[
    [1, 4],
    [2, 3]
]
{
    1: 0,
    4: 0,
    2: 1,
    3: 1
}
然后,
buildNode
函数如下所示:

var buildNode = function(index) {

    var children = nodeTargets[index].map(function(x) {
        return buildNode(x);
    });

    var parentIndex = nodeParents[index];
    var parentName;
    if (parentIndex !== undefined) {
        parentName = data.nodes[parentIndex].name;
    }

    return {
        name: data.nodes[index].name,
        parent: parentName,
        children: children
    };
};

您可以通过迭代所有
节点
并生成一个索引为键且仅为名称的对象,然后通过迭代所有
链接
并将节点与父节点和子节点一起追加来生成树结构,从而构建树

然后,您需要标记对象中的子节点,稍后它只返回非子节点

var data={nodes:[{name:“Top Level”,group:1},{name:“Level 2:A”,group:1},{name:“A的女儿”,group:1},{name:“Level 2:B”,group:1}],链接:[{source:0,target:1,value:1},{source 0,target:0,target:4,value:1},{source 1,target 2,value:1},{source 1,target 1,value:1}] },
树=函数(对象){
var o={},children={};
object.nodes.forEach(函数(a,i){
o[i]={name:a.name};
});
object.links.forEach(函数(a){
o[a.target].parent=o[a.source].name;
o[a.source]。children=o[a.source]。children | |[];
o[a.source].children.push(o[a.target]);
children[a.target]=true;
});
返回对象。键(o)。过滤器(函数(k){
返回!儿童[k];
}).map(函数(k){
返回o[k];
});
}(数据);
控制台日志(树)

.as-console-wrapper{max-height:100%!important;top:0;}
你怎么知道谁是谁的孩子,谁是谁的父母?我打赌OP会说“按
名称的值”
。欢迎使用堆栈溢出!请带我们参观一下。看起来你想让我们为你写一些代码。虽然许多用户愿意为陷入困境的程序员编写代码,但他们通常只在海报已经试图自己解决问题时才提供帮助。演示这项工作的一个好方法是包括您迄今为止编写的代码(形成一个示例)、示例输入(如果有)、预期输出和实际获得的输出(输出、回溯等)。你提供的细节越多,你可能得到的答案就越多。请检查和。@brk我已经更新了我的问题,请检查。如果有任何疑问,请告诉我。谢谢