我在一个数组data里有我所有的父辈子女,我想在每个对象上添加一个新的属性(级别)。
鉴于我的数据为
var data = [
{
id: 1,
parent_id: 0,
name: "Child1",
},
{
id: 4,
parent_id: 1,
name: "Child11",
},
{
id: 5,
parent_id: 4,
name: "Child111",
},
{
id: 11,
parent_id: 4,
name: "Child112"
},
{
id: 13,
parent_id: 11,
name: "Child1121",
},
{
id: 21,
parent_id: 11,
name: "Child1122"
},
{
id: 22,
parent_id: 11,
name: "Child1123"
},
{
id: 24,
parent_id: 1,
name: 'Child12'
}
]
我想要一个 亲子 关系基于 parent_id 并在数组的每个对象中分配一个新的属性作为level,它代表了基于其父对象的子对象的深度级别。预期的 结果是 。
var data = [
{
id: 1,
parent_id: 0, <-------represents root
name: "Child1",
level:0 <--------level based on its parent_id
},
{
id: 4,
parent_id: 1
name: "Child11",
level:1
},
{
id: 5,
parent_id: 4,
name: "Child111",
level:2
},
{
id: 11,
parent_id: 4,
name: "Child112",
level:2
},
{
id: 13,
parent_id: 11,
name: "Child1121",
level:3
},
{
id: 21,
parent_id: 11,
name: "Child1122",
level:3
},
{
id: 22,
parent_id: 11,
name: "Child1123",
level:3
},
{
id: 24,
parent_id: 1,
name: 'Child12',
level:1
}
]
我的代码
function buildTree(elements, parent_id, level = 0) {
elements.forEach(element => {
if (element['parent_id'] == parent_id) {
console.log('parent_id', parent_id);
// elements.filter(item=>item!==element);
element['level'] = level;
}
else{
buildTree(elements,parent_id,level+1);
}
})
return elements;
}
对于排序的数据,你可以取一个对象的级别数,并映射一个新的数据集。
var data = [{ id: 1, parent_id: 0, name: "Child1" }, { id: 4, parent_id: 1, name: "Child11" }, { id: 5, parent_id: 4, name: "Child111" }, { id: 11, parent_id: 4, name: "Child112" }, { id: 13, parent_id: 11, name: "Child1121" }, { id: 21, parent_id: 11, name: "Child1122" }, { id: 22, parent_id: 11, name: "Child1123" }, { id: 24, parent_id: 1, name: 'Child12' }],
levels = {},
result = data.map(o => ({
...o,
level: levels[o.id] = o.parent_id in levels
? levels[o.parent_id] + 1
: 0
}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
试试这个
let parentLevel = []
data.map(parent => {
const { parent_id } = parent
if (!parentLevel.includes(parent_id)) {
parentLevel.push(parent_id);
}
})
const updatedData = data.map(parent => {
const { parent_id } = parent
parent.level = parentLevel.indexOf(parent_id)
return parent
})
console.log(updatedData);
结果是
(8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {id: 1, parent_id: 0, name: "Child1", level: 0}
1: {id: 4, parent_id: 1, name: "Child11", level: 1}
2: {id: 5, parent_id: 4, name: "Child111", level: 2}
3: {id: 11, parent_id: 4, name: "Child112", level: 2}
4: {id: 13, parent_id: 11, name: "Child1121", level: 3}
5: {id: 21, parent_id: 11, name: "Child1122", level: 3}
6: {id: 22, parent_id: 11, name: "Child1123", level: 3}
7: {id: 24, parent_id: 1, name: "Child12", level: 1}
如果数据的排序方式不能保证父数据排在其任何子数据之前,则使用 Map
键入 id
值,这样也能提高效率(每次迭代都不需要线性查找)。
let data = [{ id: 1, parent_id: 0, name: "Child1" }, { id: 4, parent_id: 1, name: "Child11" }, { id: 5, parent_id: 4, name: "Child111" }, { id: 11, parent_id: 4, name: "Child112" }, { id: 13, parent_id: 11, name: "Child1121" }, { id: 21, parent_id: 11, name: "Child1122" }, { id: 22, parent_id: 11, name: "Child1123" }, { id: 24, parent_id: 1, name: 'Child12' }];
// optional step if you don't want to mutate the original objects in the array:
data = data.map(o => ({...o}));
const map = new Map(data.map(o => [o.id, o])).set(0, { level: -1 });
const setLevel = o => "level" in o ? o.level : (o.level = 1 + setLevel(map.get(o.parent_id)));
data.forEach(setLevel);
console.log(data);
你可以省略可选的赋值,如果你同意添加。level
属性到现有对象。但是,如果你想让原来的数据对象保持不变,而新创建的对象用于存储 level
财产,那么就把这一行保持在。