在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 object
或tree
。 根节点具有儿童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 。
-
Array.prototype.reduce
而不是Array.prototype.forEach
,因为需要一个临时variables和返回值。 -
r[a.name].children
a.children
的内容被保存并分配给a.children
。 -
节点
a
被分配给r[a.name]
。 因此,节点对象的所有属性保持不变,如prop1
…prop5
。 -
根节点被分配给
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>');