我有一个像这样的平面阵列,我应该为它构建一个平面阵列。如果pid不为null,则该对象将是其父对象的子属性。我该怎么做?
var a = [
{id: 1, pid: null},
{id: 2, pid: 1},
{id: 3, pid: 1},
{id: 4, pid: 3},
{id: 5, pid: 3}
];
期待输出:
var result = [{id: 1, children: [
{id: 2, children: []},
{id: 3, children: [{id: 4}, {id: 5}]}
]}]
答案 0 :(得分:1)
您可以使用reduce()
方法创建递归函数。
var a = [{id: 1, pid: null}, {id: 2, pid: 1}, {id: 3, pid: 1}, {id: 4, pid: 3}, {id: 5, pid: 3}];
function tree(data, parent) {
return data.reduce((r, {id,pid}) => {
if (parent == pid) {
const obj = {id}
const children = tree(data, id);
if (children.length) obj.children = children;
r.push(obj)
}
return r;
}, [])
}
const result = tree(a, null);
console.log(result);
答案 1 :(得分:1)
您可以使用单循环方法,也适用于未排序的数组。
var a = [{ id: 1, pid: null }, { id: 2, pid: 1 }, { id: 3, pid: 1 }, { id: 4, pid: 3 }, { id: 5, pid: 3 }],
tree = function (data, root) {
return data.reduce(function (o, { id, pid }) {
o[id] = o[id] || { id };
o[pid] = o[pid] || { id: pid };
o[pid].children = o[pid].children || [];
o[pid].children.push(o[id]);
return o;
}, {})[root].children;
}(a, null);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:0)
这两个使用reduce的答案都很棒,一个小问题就是有多遍,IOW:如果树很大,那么就会有很多线性搜索。
对此的一个解决方案是首先构建一个地图,然后展平地图.. mmm,实际上是扁平的,这里可能是错误的单词,也许扩展.. :)但是你明白了......
以下是一个例子。
const a = [
{id: 1, pid: null},
{id: 2, pid: 1},
{id: 3, pid: 1},
{id: 4, pid: 3},
{id: 5, pid: 3}
];
function flatern(map, parent) {
const g = map.get(parent);
const ret = [];
if (g) {
for (const id of g) {
const k = {id};
ret.push(k);
const sub = flatern(map, id);
if (sub) k.children = sub;
}
return ret;
}
return null;
}
function tree(a) {
const m = new Map();
a.forEach((i) => {
const g = m.get(i.pid);
if (!g) {
m.set(i.pid, [i.id]);
} else {
g.push(i.id);
}
});
return flatern(m, null);
}
console.log(tree(a));

.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 3 :(得分:0)
var a = [
{id: 1, pid: null},
{id: 2, pid: 1},
{id: 3, pid: 1},
{id: 4, pid: 3},
{id: 5, pid: 3}
];
function processToTree(data) {
const map = {};
data.forEach(item => {
map[item.id] = item;
item.children = [];
});
const roots = [];
data.forEach(item => {
const parent = map[item.pid];
if (parent) {
parent.children.push(item);
}
else {
roots.push(item);
}
});
return roots;
}
今天学会了这种方法,我认为这是最好的