如何过滤FileTreeProps结构文件树,保留满足相似度要求的isMat节点路径?
文件树过滤逻辑实现问题
类型定义
interface FileTreeProps { name: string; isMat?: boolean; children?: FileTreeProps[]; }
需求说明
用户提交查询后,需生成过滤后的文件树,满足以下要求:
- 仅保留指向
isMat属性为true的子节点的完整路径 - 前两层子节点均为父文件夹,永远不会出现
isMat=true的情况 - 仅保留与查询字符串相似度大于0.25的子节点(已具备字符串相似度校验工具)
典型文件结构示例
{ "name": "SubtlePBR", "children": [ { "name": "assets", "children": [ { "name": "minecraft", "children": [ { "name": "textures", "children": [ { "name": "block", "children": [ { "name": "acacia_leaves", "children": [], "isMat": true }, { "name": "acacia_log", "children": [], "isMat": true } ] } ] } ] } ] } ] }
请问该如何实现这一过滤逻辑?
实现方案
核心思路
- 采用递归遍历整个文件树,从
isMat=true的叶子节点反向筛选路径——只有子节点存在符合条件的路径时,父节点才会被保留。 - 前两层节点直接递归处理子节点,无需判断
isMat;从第三层开始,遇到isMat=true的节点先做相似度校验,达标才保留。 - 处理过程中复制节点避免修改原始数据,同时自动合并同一父节点下的有效子节点,不会产生重复路径。
TypeScript代码实现
直接使用你已有的字符串相似度校验函数:
import { calculateSimilarity } from './utils/similarity'; function filterFileTree(tree: FileTreeProps, query: string): FileTreeProps | null { // 初始化过滤后的节点,复制原节点名称 const filteredNode: FileTreeProps = { name: tree.name, children: [] }; // 无子女节点时直接处理当前节点逻辑 if (!tree.children) { if (tree.isMat) { return calculateSimilarity(tree.name, query) > 0.25 ? { ...tree, children: [] } : null; } return null; } // 遍历处理所有子节点 for (const child of tree.children) { const filteredChild = filterFileTree(child, query); if (filteredChild) { filteredNode.children.push(filteredChild); } } // 当前节点是目标叶子节点时,单独做相似度校验 if (tree.isMat) { const similarity = calculateSimilarity(tree.name, query); return similarity > 0.25 ? { ...tree, children: [] } : null; } // 子节点全部被过滤时,当前节点无需保留 return filteredNode.children.length > 0 ? filteredNode : null; }
关键细节说明
- 递归逻辑:每一层节点先处理所有子节点,仅当子节点存在有效路径时才保留当前节点,自动实现“保留完整路径”的需求。
- 叶子节点校验:遇到
isMat=true的节点时,直接用相似度工具判断,大于0.25才保留,否则整个路径会被截断。 - 前两层兼容:因为前两层不会出现
isMat=true,递归会自然深入到下层,无需额外层级判断,逻辑更简洁。 - 数据安全:所有节点均为复制后处理,不会修改原始文件树数据。
调用示例
// 原始文件树数据 const originalTree = { "name": "SubtlePBR", "children": [ { "name": "assets", "children": [ { "name": "minecraft", "children": [ { "name": "textures", "children": [ { "name": "block", "children": [ { "name": "acacia_leaves", "children": [], "isMat": true }, { "name": "acacia_log", "children": [], "isMat": true } ] } ] } ] } ] } ] }; // 查询字符串 const query = "acacia"; // 执行过滤 const filteredTree = filterFileTree(originalTree, query); console.log(filteredTree);
运行后将得到仅包含根节点到两个符合条件叶子节点的完整路径树。
内容的提问来源于stack exchange,提问作者Zoclhas
相关产品推荐
相关产品推荐

