Skip to content

使用深度优先搜索查找父子级关联的数据

源数据结构如下:

const treeAllData=[
{id: 1, parentId: 0},
{id: 2, parentId: 1},
{id: 3, parentId: 2},
{id: 4, parentId: 2},
{id: 5, parentId: 4},
{id: 6, parentId: 5},
]

查找 newArr = [{id: 2, parentId: 1}, {id: 3, parentId: 2}] 的所有父级和所有子级,注意,父级可能有父级的父级,子级可能有子级的子级

/**
* 查找出父级和子级,返回列表
*
* 查父级:当前的 parentId,是其他的 id(同级只有一个)
* 查子级:当前的 id,是其他的 parentId(同级可能有多个)
*/
export const findParentAndChildren = (treeAllData, targetArr) => {
if (!targetArr.length) return [];
const result = new Set();
// 创建映射加速查找
const nodeMap = new Map(treeAllData.map((node) => [node.id, node]));
// 查找所有父级节点
const findParentsByStack = (startId) => {
let currentId = startId;
while (currentId !== 0) {
const parent = nodeMap.get(currentId) as Record<string, any>;
if (parent) {
result.add(parent);
currentId = parent.parentId;
} else {
break;
}
}
};
// 创建父节点到子节点的映射,一个父节点可能有多个子节点
const childrenMap = new Map();
treeAllData.forEach((node) => {
if (!childrenMap.has(node.parentId)) {
childrenMap.set(node.parentId, []);
}
childrenMap.get(node.parentId).push(node);
});
// 查找所有子级节点
const findChildrenByStack = (startId) => {
const stack = [startId];
while (stack.length > 0) {
const currentId = stack.pop();
// 获取当前节点的所有子节点
const children = childrenMap.get(currentId) || [];
for (const child of children) {
if (!result.has(child)) {
result.add(child);
stack.push(child.id);
}
}
}
};
// 处理目标数组
targetArr.forEach((node) => {
result.add(node);
findParentsByStack(node.parentId);
findChildrenByStack(node.id);
});
return Array.from(result) as never[];
};