求助:基于Reference JSON过滤并扩展Input JSON节点的实现
问题描述
我有两个JSON数据:一个是带层级节点结构的Input JSON,另一个是键值对形式的Reference JSON。需要完成两个核心操作:
- 过滤Input JSON,仅保留
id存在于Reference JSON中的元素 - 按照期望输出的要求,为指定节点补充新的子节点
我尝试用递归逻辑实现,但未达到预期效果,以下是具体数据和尝试的代码:
Input JSON
[ { "id": "birds-group", "type": "group", "children": [ { "id": "Birds Types", "children": [ { "id": "Flying Birds", "children": [{ "id": "Parrot" }, { "id": "Crow" }] }, { "id": "Non-Flying Birds", "children": [{ "id": "Peacock" }] } ] } ] }, { "id": "animal-group", "type": "group", "children": [ { "id": "animal types", "children": [ { "id": "Vegan Animals" }, { "id": "Amphibians" }, { "id": "Forest Animals", "children": [{ "id": "Lion" }, { "id": "Tiger" }] }, { "id": "Domestic Animals", "children": [{ "id": "Cow" }] } ] } ] } ]
Reference JSON
{ "Birds Types": { "Flying Birds": ["Parrot", "Crow"], "Non-Flying Birds": ["Peacock"] }, "animal types": { "Vegan Animals": [], "Amphibians": [], "Forest Animals": ["Lion", "Tiger"], "Domestic Animals": ["Cow"] } }
期望输出
[ { "id": "birds-group", "type": "group", "children": [ { "id": "Birds Types", "children": [ { "id": "Flying Birds", "children": [ { "id": "Parrot" }, { "id": "Crow" }, { "id": "Sparrow" } ] }, { "id": "Non-Flying Birds", "children": [{ "id": "Peacock" }, { "id": "Emu" }] } ] } ] }, { "id": "animal-group", "type": "group", "children": [ { "id": "animal types", "children": [ { "id": "Vegan Animals" }, { "id": "Amphibians" }, { "id": "Forest Animals", "children": [{ "id": "Lion" }, { "id": "Tiger" }] }, { "id": "Domestic Animals", "children": [{ "id": "Cow" }, { "id": "Dog" }] } ] } ] } ]
尝试的代码
function filterChildren(children, reference) { return children.filter(child => { if (child.id in reference) { if (child.children && reference[child.id].children) { child.children = filterChildren(child.children, reference[child.id].children); } return true; } return false; }); } function filterData(data, reference) { return data.map(item => { if (item.id in reference) { if (item.children) { item.children = filterChildren(item.children, reference[item.id].children); } return item; } }).filter(item => item !== undefined); }
解决方案
原代码的核心问题是:未处理子节点补充逻辑,且对Reference JSON的结构访问方式错误。以下是修正后的实现:
// 定义需要补充的新子节点映射(可根据实际需求调整或从其他数据源获取) const additionalChildren = { "Flying Birds": ["Sparrow"], "Non-Flying Birds": ["Emu"], "Domestic Animals": ["Dog"] }; // 递归处理单个节点:过滤合法节点 + 补充新子节点 function processNode(node, reference) { // 创建节点副本,避免修改原输入数据 const newNode = { ...node }; // 仅处理id在reference中的节点 if (reference && newNode.id in reference) { const refEntry = reference[newNode.id]; // 处理层级节点(reference中对应值为对象) if (typeof refEntry === 'object' && !Array.isArray(refEntry)) { let processedKids = []; // 保留原输入中符合条件的子节点 if (newNode.children) { processedKids = newNode.children .filter(child => child.id in refEntry) .map(child => processNode(child, refEntry)); } // 补充新子节点 if (additionalChildren[newNode.id]) { additionalChildren[newNode.id].forEach(id => { processedKids.push({ id }); }); } newNode.children = processedKids.length ? processedKids : undefined; } // 处理叶子节点(reference中对应值为数组) else if (Array.isArray(refEntry)) { const allChildIds = [...refEntry, ...(additionalChildren[newNode.id] || [])]; newNode.children = allChildIds.map(id => ({ id })); } return newNode; } // id不在reference中的节点直接丢弃 return undefined; } // 处理顶层数据 function processData(data, reference) { return data.map(group => { const newGroup = { ...group }; // 顶层group的id不在reference中,直接处理其children if (newGroup.children) { newGroup.children = newGroup.children .map(child => processNode(child, reference)) .filter(node => node !== undefined); } return newGroup; }); } // 使用示例 const inputData = [/* 你的Input JSON数据 */]; const referenceData = {/* 你的Reference JSON数据 */}; const finalResult = processData(inputData, referenceData); console.log(JSON.stringify(finalResult, null, 2));
代码说明
additionalChildren:存储需要新增的子节点ID映射,可根据业务需求动态调整来源processNode:递归处理每个节点,创建副本避免污染原数据,同时完成节点过滤和子节点补充processData:专门处理顶层的group节点(这类节点的id不在Reference中),仅处理其内部的子节点
内容的提问来源于stack exchange,提问作者Sreeni
相关产品推荐
相关产品推荐

