You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:基于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));

代码说明

  1. additionalChildren:存储需要新增的子节点ID映射,可根据业务需求动态调整来源
  2. processNode:递归处理每个节点,创建副本避免污染原数据,同时完成节点过滤和子节点补充
  3. processData:专门处理顶层的group节点(这类节点的id不在Reference中),仅处理其内部的子节点

内容的提问来源于stack exchange,提问作者Sreeni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 00:07:08