如何过滤带命名键的JavaScript树形结构对象?
带命名键树形结构的搜索过滤实现
我有一个如下所示的带命名键的树形结构对象,需要根据label字段进行搜索过滤:
- 当搜索匹配某个节点的
label时,保留该节点的所有祖先节点(完整路径) - 同时保留匹配节点的所有子节点
- 过滤掉所有不相关的分支
const tree = { "28": { "label": "lorem", "children": { "188": { "label": "ipsum", "children": { "482": { "label": "fish", "children": { "185": { "label": "dog" }, "289": { "label": "cat" } } } } } } }, "33": { "label": "water", "children": { "95": { "label": "fire", "children": { "181": { "label": "gas", "children": { "100": { "label": "station" } } }, "182": { "label": "", "children": { "100": { "label": "sushi" } } } } } } } }
搜索示例
- 搜索
'fish'时,输出结果:
{ "28": { "label": "lorem", "children": { "188": { "label": "ipsum", "children": { "482": { "label": "fish", "children": { "185": { "label": "dog" }, "289": { "label": "cat" } } } } } } } }
- 搜索
'dog'时,输出结果:
{ "28": { "label": "lorem", "children": { "188": { "label": "ipsum", "children": { "482": { "label": "fish", "children": { "185": { "label": "dog" } } } } } } } }
解决方案
针对这种带命名键的树形结构,我们可以实现一个递归过滤函数,核心逻辑是:
- 遍历当前层级的所有命名键节点
- 对每个节点,检查自身
label是否匹配搜索关键词,或者子节点中是否存在匹配项 - 如果存在匹配,构建新的节点对象,保留当前节点的
label,并递归处理children,只保留有匹配的子分支 - 最终收集所有符合条件的节点分支,组成过滤后的树形结构
完整实现代码:
function filterTree(tree, searchTerm) { const filtered = {}; // 遍历当前层级的所有命名键节点 Object.entries(tree).forEach(([key, node]) => { let hasMatch = false; let filteredChildren = {}; // 如果有子节点,递归过滤子节点 if (node.children) { filteredChildren = filterTree(node.children, searchTerm); hasMatch = Object.keys(filteredChildren).length > 0; } // 检查当前节点label是否匹配 if (node.label.includes(searchTerm)) { hasMatch = true; // 当前节点匹配时,保留所有子节点 filteredChildren = node.children || {}; } // 如果当前节点或子节点有匹配,加入结果 if (hasMatch) { filtered[key] = { label: node.label, ...(Object.keys(filteredChildren).length > 0 && { children: filteredChildren }) }; } }); return filtered; } // 调用示例 console.log(JSON.stringify(filterTree(tree, 'fish'), null, 2)); console.log(JSON.stringify(filterTree(tree, 'dog'), null, 2));
逻辑说明
- 递归遍历每个层级的命名键节点,避免遗漏任何分支
- 当当前节点的
label匹配关键词时,直接保留该节点的所有子节点 - 当子节点中有匹配项时,保留当前节点,并只保留有匹配的子分支
- 最终只返回包含匹配路径的树形结构,过滤掉所有无关分支
内容的提问来源于stack exchange,提问作者Drun555
相关产品推荐
相关产品推荐

