在javascript中将数组转换为嵌套对象

我有典型的组织hierarchy 。 例如。

 D,E is reporting to B. B,C is reporting to A. 

A是最顶端的节点。 但是,我收到这个数据作为一个平面数组与指向父母的属性。

  [{ name: "A", parent: null }, { name: "B", parent: "A" }, { name: "C", parent: "A" }, { name: "D", parent: "B" }, { name: "E", parent: "B" }] 

但我想将其转换为single nested objecttree 。 根节点具有儿童embedded的子属性,每个子节点都有自己的子属性。

  { name: "A", children: [{ name: "C" children: [{ name: "D" },{ name: "E" }] },{ name: "C" }] } 

我怎样才能有效地在JavaScript中做到这一点?

与其他解决scheme不同,它使用单个循环 – 数据顺序不重要 – 示例与问题顺序不同

 var peeps = [ { name: "D", parent: "B" }, { name: "B", parent: "A" }, { name: "A", parent: null }, { name: "C", parent: "A" }, { name: "E", parent: "B" } ]; var tree; var obj = {}; peeps.forEach(function (peep) { var name = peep.name, parent = peep.parent, a = obj[name] || { name: name }; if (parent) { obj[parent] = obj[parent] || { name: parent }; obj[parent].children = obj[parent].children || []; obj[parent].children.push(a); } else { tree = obj[name]; } obj[name] = obj[name] || a; }); console.log(tree); 

你可以使用while循环来做到这一点:

 var data = [ { name: "A", parent: null }, { name: "B", parent: "A" }, { name: "C", parent: "A" }, { name: "D", parent: "B" }, { name: "E", parent: "B" } ]; var root = data.find(function(item) { return item.parent === null; }); var tree = { name: root.name }; var parents = [tree]; while (parents.length > 0) { var newParents = []; parents.forEach(function(parent) { var childs = data.filter(function(item) { return item.parent == parent.name }).forEach(function(child) { var c = { name: child.name }; parent.children = parent.children || []; parent.children.push(c); newParents.push(c); }); }); parents = newParents; } console.log(tree); 

这个解决scheme包含了Jaromanda X的解决scheme 。

  1. Array.prototype.reduce而不是Array.prototype.forEach ,因为需要一个临时variables和返回值。

  2. r[a.name].children a.children的内容被保存并分配给a.children

  3. 节点a被分配给r[a.name] 。 因此,节点对象的所有属性保持不变,如prop1prop5

  4. 根节点被分配给r._供以后使用。

 var data = [ { name: "D", parent: "B", prop1: 'prop1' }, { name: "B", parent: "A", prop2: 'prop2' }, { name: "A", parent: null, prop3: 'prop3' }, { name: "C", parent: "A", prop4: 'prop4' }, { name: "E", parent: "B", prop5: 'prop5' } ], tree = data.reduce(function (r, a) { a.children = r[a.name] && r[a.name].children; r[a.name] = a; if (a.parent) { r[a.parent] = r[a.parent] || {}; r[a.parent].children = r[a.parent].children || []; r[a.parent].children.push(a); } else { r._ = a; } return r; }, {})._; document.write('<pre>' + JSON.stringify(tree, 0, 4) + '</pre>');