搞定啦
我不想再被递归爆锤啦
const arr = [
{
id: 1,
name: "Node 1",
children: [
{
id: 2,
name: "Node 1.1",
children: [
{
id: 3,
name: "Node 1.1.1",
children: [
{
id: 31,
name: "独特的节点",
children: [],
},
],
},
{ id: 4, name: "Node 1.1.2", children: [] },
],
},
{ id: 5, name: "Node 1.2", children: [] },
],
},
{
id: 6,
name: "Node 2",
children: [{ id: 7, name: "Node 2.1", children: [] }],
},
];
常规做法
//递归三要素 : 条件 、 出口 、明确函数作用
function addAttribute(arr) {
if (!(arr instanceof Array) || arr.length == 0) return; // 递归出口
// 做什么:新增属性
return arr.map((item) => {
item.checked = false;
if (item.children && item.children.length) {
addAttribute(item.children);
}
return item
});
}
console.log(addAttribute(arr));
优化
function addAttribute1(arr) {
if (!(arr instanceof Array) || arr.length == 0) return; // 递归出口
return arr.map((item) => {
item.checked = false;
if (item.children && item.children.length) {
addAttribute(item.children);
}
return item
});
}
function addAttribute2(arr) {
if (!(arr instanceof Array) || arr.length == 0) return []; // 递归出口
return arr.map((item) => {
return {
...item,
checked: false,
children:
item.children && item.children.length
? addAttribute(item.children)
: [],
};
});
}
这两个方法都可以实现为传入的数组添加`checked`属性,并递归地为子元素添加相同的属性。它们的主要区别在于返回值和对原始数组的修改方式。
优点和区别如下:
`addAttribute1`方法:
- 优点:
- 直接在原始数组上修改,不会创建新的数组对象。
- 返回原始数组本身,不需要额外的变量来接收返回值。
- 区别:
- 返回值是原始数组本身,没有创建新的数组副本。
- `addAttribute1`方法没有返回值处理,调用者无法获取修改后的数组。
`addAttribute2`方法:
- 优点:
- 创建了一个新的数组副本,不会直接修改原始数组。
- 返回新的数组副本,调用者可以获取修改后的数组。
- 区别:
- 创建了新的对象副本,可能会占用额外的内存空间。
- 需要使用额外的变量来接收返回值。
根据你的需求和代码使用场景,你可以选择其中一个方法。如果你需要直接修改原始数组,并且不需要获取返回值,可以选择`addAttribute1`方法。如果你需要保留原始数组的不变性,并且需要获取修改后的数组,可以选择`addAttribute2`方法。
// 定义一个函数来设置节点的parentId属性
setParentId(tree, parentId = null) {
tree.forEach((node) => {
node.parentId = parentId;
if (node.children && node.children.length > 0) {
this.setParentId(node.children, node.id); // 递归调用,设置子节点的parentId属性
}
});
},