在实现树形结构转为列表的应用场景中,过程如下:
const data = [
{
id: "1",
name: "父节点1",
children: [
{
id: "1-1",
name: "子节点1-1",
children: [
{
id: "1-1-1",
name: "子节点1-1-1",
},
{
id: "1-1-2",
name: "子节点1-1-2",
},
],
},
],
},
{
id: "2",
name: "父节点2",
children: [
{
id: "2-1",
name: "子节点2-1",
},
],
},
];
转化为:
[
{ id: '1', name: '父节点1' },
{ id: '1-1', name: '子节点1-1' },
{ id: '1-1-1', name: '子节点1-1-1' },
{ id: '1-1-2', name: '子节点1-1-2' },
{ id: '2', name: '父节点2' },
{ id: '2-1', name: '子节点2-1' }
]
逻辑其实比较简单,与数组扁平化的思想好像差不太多,本质都是对data遍历,然后处理。在该情境下即为判断data中是否有children项,若是含有children项也要对该data实现扁平化的操作。
我采用reduce方法进行迭代处理,但在输出结果时,发现只能输出第一层的元素,console.log进行排查,发现是数组concat方法使用错误,数组concat方法不改变原数组而是返回一个新的数组!!!这里的问题似乎已经犯了两次,代码如下:
function treeToList(tree) {
let ans = tree.reduce((prev, cur) => {
if (cur.children && cur.children.length) {
let child = treeToList(cur.children);
delete cur.children;
console.log("child为", child);
prev.push(cur);
prev.concat(child);//错误写法
console.log("加入子数组后:", prev);
} else {
prev.push(cur);
}
return prev;
}, []);
return ans;
}
规范代码:
function treeToList(tree) {
let ans = tree.reduce((prev, cur) => {
if (cur.children && cur.children.length) {
let child = treeToList(cur.children);
delete cur.children;
prev = prev.concat(cur, child);
} else {
prev = prev.concat(cur);
}
return prev;
}, []);
return ans;
}