从平面对象数组构建对象树数组[重复]
Posted
技术标签:
【中文标题】从平面对象数组构建对象树数组[重复]【英文标题】:Building tree array of objects from flat array of objects [duplicate] 【发布时间】:2017-10-20 10:48:57 【问题描述】:我想从平面数组构建一个树数组:
这是平面数组:
nodes = [
id: 1, pid: 0, name: "kpittu",
id: 2, pid: 0, name: "news",
id: 3, pid: 0, name: "menu",
id: 4, pid: 3, name: "node",
id: 5, pid: 4, name: "subnode",
id: 6, pid: 1, name: "cace"
];
注意:id = 节点id; pid = 父节点 ID。
我想把它变成这个数组:
nodes = [
id: 1,
name: 'kpittu',
childs: [
id: 6,
name: 'cace'
]
,
id: 2,
name: 'news'
,
id: 3,
name: 'menu',
childs: [
id: 4,
name: 'node',
childs: [
id: 5,
name: 'subnode'
]
]
];
我尝试使用递归函数来实现预期结果,但我正在寻找更好的方法。感谢您的回复。
【问题讨论】:
请同时添加您的功能。 建议,如果你自己不弄清楚,你将无法学习或练习你的递归知识,而是回答这个问题的人 【参考方案1】:您可以使用哈希表并将每个循环中的id
和pid
作为连接节点。
此提议也适用于未排序的数据。
var nodes = [ id: 6, pid: 1, name: "cace" , id: 1, pid: 0, name: "kpittu" , id: 2, pid: 0, name: "news" , id: 3, pid: 0, name: "menu" , id: 4, pid: 3, name: "node" , id: 5, pid: 4, name: "subnode" ],
tree = function (data, root)
var r = [], o = ;
data.forEach(function (a)
if (o[a.id] && o[a.id].children)
a.children = o[a.id] && o[a.id].children;
o[a.id] = a;
if (a.pid === root)
r.push(a);
else
o[a.pid] = o[a.pid] || ;
o[a.pid].children = o[a.pid].children || [];
o[a.pid].children.push(a);
);
return r;
(nodes, 0);
console.log(tree);
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
【参考方案2】:你也可以使用 ES6 中引入的 Map 对象。
let nodes = [
id: 1, pid: 0, name: "kpittu" ,
id: 2, pid: 0, name: "news" ,
id: 3, pid: 0, name: "menu" ,
id: 4, pid: 3, name: "node" ,
id: 5, pid: 4, name: "subnode" ,
id: 6, pid: 1, name: "cace"
];
function toTree(arr)
let arrMap = new Map(arr.map(item => [item.id, item]));
let tree = [];
for (let i = 0; i < arr.length; i++)
let item = arr[i];
if (item.pid)
let parentItem = arrMap.get(item.pid);
if (parentItem)
let children = parentItem;
if (children)
parentItem.children.push(item);
else
parentItem.children = [item];
else
tree.push(item);
return tree;
let tree = toTree(nodes);
console.log(tree);
【讨论】:
【参考方案3】:使用 Array#reduce 和辅助对象进行迭代:
var nodes = [
id: 1, pid: 0, name: "kpittu",
id: 2, pid: 0, name: "news",
id: 3, pid: 0, name: "menu",
id: 4, pid: 3, name: "node",
id: 5, pid: 4, name: "subnode",
id: 6, pid: 1, name: "cace"
];
const helper = nodes.reduce((h, o) => (h[o.id] = Object.assign(, o), h), Object.create(null));
const tree = nodes.reduce((t, node) =>
const current = helper[node.id];
if(current.pid === 0) // if it doesn't have a parent push to root
t.push(current);
else
helper[node.pid].children || (helper[node.pid].children = []) // add the children array to the parent, if it doesn't exist
helper[node.pid].children.push(current); // push the current item to the parent children array
return t;
, []);
console.log(tree);
【讨论】:
以上是关于从平面对象数组构建对象树数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章