基于路径的深度对象搜索:树遍历匹配需求技术求助
树遍历匹配查找实现方案
核心功能说明
需要实现两个关键逻辑:
- 递归遍历对象树,定位目标文本所在的具体路径
- 基于该路径生成模板路径(将所有数组索引替换为通配符
[*]),遍历所有符合模板结构的节点,提取对应值
完整代码实现
// 递归查找目标文本,返回其完整路径 function findText(obj, target, currentPath = '') { for (const key of Object.keys(obj)) { const newPath = currentPath ? `${currentPath}.${key}` : key; const value = obj[key]; if (value === target) { return newPath; } else if (Array.isArray(value)) { for (let i = 0; i < value.length; i++) { const arrayPath = `${newPath}[${i}]`; const result = findText(value[i], target, arrayPath); if (result) return result; } } else if (typeof value === 'object' && value !== null) { const result = findText(value, target, newPath); if (result) return result; } } return null; } // 将具体路径转换为模板路径(数组索引替换为[*]) function convertPathToTemplate(path) { return path.replace(/\[\d+\]/g, '[*]'); } // 根据模板路径遍历所有符合结构的节点,提取对应值 function findObjectInTree(obj, templatePath) { const result = []; const segments = templatePath.split('.'); function traverse(currentObj, segmentIndex) { if (segmentIndex === segments.length) { result.push(currentObj); return; } const segment = segments[segmentIndex]; if (segment.endsWith('[*]')) { const key = segment.slice(0, -3); const array = currentObj[key]; if (Array.isArray(array)) { for (const item of array) { traverse(item, segmentIndex + 1); } } } else { if (currentObj && typeof currentObj === 'object' && segment in currentObj) { traverse(currentObj[segment], segmentIndex + 1); } } } traverse(obj, 0); return result; }
测试示例
// 测试数据 const DATA = { a:[ { b:{ c:[{value:'A'}]}}, { b:{ c:[{foo:1},{value:'B'}]}}, { b:{ c:[{value:'C', b: { c: [ {value:'D'} ] } }] }} ], a1:[{ b:{ c:[{value:'AA'}]}}] }; // 查找目标文本路径 const pathToMatch = findText(DATA, 'A'); console.log(pathToMatch); // 输出: a[0].b.c[0].value // 转换为模板路径 const templatePath = convertPathToTemplate(pathToMatch); console.log(templatePath); // 输出: a[*].b.c[*].value // 提取所有匹配值 const matchedValues = findObjectInTree(DATA, templatePath); console.log(matchedValues); // 输出: ['A', 'B', 'C']
结果说明
A/B/C被返回:三者路径完全符合a[*].b.c[*].value模板,仅数组索引不同,路径深度和键结构一致D被排除:路径为a[*].b.c[*].b.c[*].value,比模板多两层嵌套,深度不符AA被排除:路径根键为a1而非a,结构不符
内容的提问来源于stack exchange,提问作者Ycon
相关产品推荐
相关产品推荐

