JS递归遍历树结构 子项ID匹配父级ID时添加isDisable属性
实现方案
直接用深度优先遍历递归处理树结构即可,核心是遍历过程中维护当前节点所有祖先的ID集合,用来判断当前节点是否和任意父级ID重复。
具体实现代码如下:
const someSearchFunction = (data) => { const traverse = (nodeList, parentIds) => { return nodeList.map(node => { // 校验当前节点ID是否存在于父级ID集合中 const isDisable = parentIds.has(node.id); // 生成子节点遍历用的ID集合,追加当前节点ID const childParentIds = new Set(parentIds); childParentIds.add(node.id); return { ...node, isDisable, children: Array.isArray(node.children) ? traverse(node.children, childParentIds) : [] } }) } // 根节点无父级,传入空ID集合 return traverse(data, new Set()); }
关键说明
- 用
Set存储父级ID,查询效率比数组includes高很多,大体量树数据下性能优势明显 - 每次递归处理子节点前都新建
Set实例,不会修改上层传入的ID集合,避免不同树分支的ID互相干扰,出现跨分支误标记的问题 - 全程没有修改原始输入的data数据,返回的是全新拷贝的结构,不会产生原始数据被篡改的副作用
拿你提供的原始测试数据调用这个函数,输出结果完全符合预期:根层级的节点isDisable均为false,所有子节点只要在自身到根节点的路径上存在同ID的父/祖先节点,就会被标记isDisable: true。
注:你给出的期望输出示例里有一处语法笔误,id为MT12的节点
children: []后缺失逗号,实际运行代码时不会出现这类问题。
内容的提问来源于stack exchange,提问作者Oleh
相关产品推荐
相关产品推荐

