课程名称:2周刷完100道前端优质面试真题
课程章节:第9章 前端面试技能拼图7 :分析和解决问题的思路 - 可以独立解决问题
主讲老师:双越
课程内容:
今天学习的内容包括:
9-5 -把一个数组转换为树(11:26)
9-6 -【连环问】把一个树转换为数组
这一章主要是讲分析解决问题,避免踩坑。
课程收获:
这两节主要是树和数组的相互转换。
-
数组转树
课程提供的方法对应数组本身已按 parentId 排序后的方法。
思路:
- 用 map 存储 id 和 子树之间的关系。由于已按 parentId 排序,故当前节点一定可在 map 找到父节点。
- 遍历数组,依次把当前节点存入 map,把当前节点放入父节点 children, 判断当前节点是否为根节点。
const arr2Tree = (arr) => {
let root = null;
const map = new Map();
arr.forEach((ele) => {
const { id, name, parentId } = ele;
const node = {
id,
name,
};
map.set(id, node);
const pNode = map.get(parentId);
if (pNode) {
pNode.children
? pNode.children.push(node)
: (pNode.children = [node]);
}
if (parentId === 0) {
root = node;
}
});
return root;
};
const arr = [
{ id: 1, name: "部门A", parentId: 0 }, // 0 代表顶级节点,无父节点
{ id: 2, name: "部门B", parentId: 1 },
{ id: 3, name: "部门C", parentId: 1 },
{ id: 4, name: "部门D", parentId: 2 },
{ id: 5, name: "部门E", parentId: 2 },
{ id: 6, name: "部门F", parentId: 3 },
];
const tree = arr2Tree(arr);
console.info(tree);
-
树转数组
课程提供的思路为以map存储当前节点和父节点的映射。
广度优先遍历树结构,用队列把当前节点和子节点一层层入队。子节点入队时存储与父节点的关系。
const tree2Arr = (root) => {
if (!root) return [];
const map = new Map();
let arr = [];
let queue = [root];
while(queue.length > 0) {
const node = queue.shift();
if (!node) {
break;
}
const { id, name, children = [] } = node;
const pNode = map.get(node);
const parentId = pNode?.id || 0;
arr.push({
id,
name,
parentId,
})
if (children.length) {
children.forEach(ele => {
map.set(ele, node);
});
queue = queue.concat(children);
}
}
return arr;
}
const arrRes = tree2Arr(JSON.parse(JSON.stringify(tree)));
console.info(arrRes);
以上结束。