2

Sorry for the confusing title... I don't know a better summery.

I have an Array of Objects. Some of these Objects have a reference to it's parent Object. Something like that:

data: 
[
  {id: 2, parent: 1},
  {id: 1},
  {id: 3, parent: 1},
  {id: 5, parent: 3},
  {id: 4, parent: 3},
  {id: 6, parent: 2} 

]

What I want to do, is creating an Object out of this Array where the child objects are nested inside their parents. Like that:

data: {
  id: 1,
  children: [
    {
      id:2,
      children: [
        {id: 6}
      ]
    },
    {
      id:3,
      children: [
        {id: 4},
        {id: 5}
      ]
    }
  ]
}

Does anyone know a smart way of doing this? I know I have to itterate through every Object of this Array and check if there is a parent. But how can I actually create this Object?

4

1 回答 1

2

不确定这是不是最好的方法,但至少这是一种方法。

  1. 首先在节点上循环:
    • id通过它们的( nodes)将节点放入查找表中。
    • 找到root节点(没有 的单个节点parent)。
  2. 第二个循环(查找表完成):
    • 检查 是否nodeparent(对于除 之外的每个节点都为真root)。
    • parent通过在查找表中查找 id 来获取节点。
    • 获取parent.children数组,如果它不存在则创建它。
    • 将此添加node到该数组中。
    • 删除parentthis 的属性node

请注意,这会更改对象中的原始节点data对象。这是有意的,因为树是通过在父节点中存储对其他节点的引用来构建的。如果您需要保持原始节点data完好无损,则应在构建查找表时克隆节点对象。例如,您可以node = $.extend({}, node);在查找循环中添加为第一行forEach(使用 jQuery 时)。

这是一个实现和演示

var data = [
  {id: 2, parent: 1},
  {id: 1},
  {id: 3, parent: 1},
  {id: 5, parent: 3},
  {id: 4, parent: 3},
  {id: 6, parent: 2}
];

// Node lookup table
var nodes = {};
// Root node
var root = null;
// Fill lookup table and find root
data.forEach(function(node) {
    nodes[node.id] = node;
    // Assuming only one root node
    if(!("parent" in node)) {
        root = node;
    }
});
// Build tree
for(var id in nodes) {
    var node = nodes[id];
    if("parent" in node) {
        // Add to children of parent
        var parent = nodes[node.parent];
        (parent.children = parent.children || []).push(node);
        // Remove parent property (optional)
        delete node.parent;
    }
}
console.log(JSON.stringify(root));
于 2013-07-07T10:13:18.933 回答