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

如何递归删除JSON中props.id为指定值的嵌套组件对象

问题描述

需要移除JSON结构中所有props.id等于"companyType"的组件对象,编写的递归函数未生效,怀疑是扩展运算符的递归处理存在问题。

原始JSON结构

{
  "mode": "onChange",
  "component": "basic",
  "props": {
    "children": [
      {
        "component": "Layout.row",
        "props": {
          "children": [
            {
              "component": "Layout.column",
              "props": {
                "md": 12,
                "lg": 3,
                "children": [
                  {
                    "component": "Layout.label",
                    "props": {
                      "label": "Description"
                    }
                  }
                ]
              }
            },
            {
              "component": "Layout.column",
              "props": {
                "md": 12,
                "lg": 8,
                "children": [
                  {
                    "component": "Control.textarea",
                    "control": {
                      "schemaPath": "desc",
                      "message": {
                        "required": "ABC Description is required"
                      }
                    },
                    "props": {
                      "id": "desc",
                      "name": "desc",
                      "label": "XYZ Description"
                    }
                  }
                ]
              }
            }
          ]
        }
      },
      {
        "component": "Layout.row",
        "props": {
          "id": "companyType",
          "children": [
            {
              "component": "Layout.column",
              "props": {
                "md": 12,
                "lg": 3,
                "children": [
                  {
                    "component": "Layout.label",
                    "props": {
                      "id": "companyType",
                      "label": "Company Type"
                    }
                  }
                ]
              }
            },
            {
              "component": "Layout.column",
              "props": {
                "md": 12,
                "lg": 8,
                "children": [
                  {
                    "component": "Control.switch",
                    "control": {
                      "schemaPath": "companyType",
                      "message": {}
                    },
                    "props": {
                      "id": "companyType",
                      "name": "companyType",
                      "label": "Company Type",
                      "moreText": "XYZ",
                      "labelPlacement": "end"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  }
}

现有递归函数(未生效)

export const delChildInJSON = (input, childId) => {
  if (input.props) {
    if (input.props.id && input.props.id === childId) {
      console.log("found childId::" + childId);
      return {};
    }
    if (input.props.children && input.props.children.length) {
      const children = input.props.children.map(element => {
        return delChildInJSON(element, childId);
      });
      return { ...input, {...input.props, children: children }};
    }
  }
};

测试代码

const json = '{"mode": "onChange","component": "basic","props": {"children": [{"component": "Layout.row","props": {"children": [{"component": "Layout.column","props": {"md": 12,"lg": 3,"children": [{"component": "Layout.label","props": {"label": "Description"}}]}},{"component": "Layout.column","props": {"md": 12,"lg": 8,"children": [{"component": "Control.textarea","control": {"schemaPath": "desc","message": {"required": "ABC Description is required"}},"props": {"id": "desc","name": "desc","label": "XYZ Description"}}]}}]}},{"component": "Layout.row","props": {"id": "companyType","children": [{"component": "Layout.column","props": {"md": 12,"lg": 3,"children": [{"component": "Layout.label","props": {"id": "companyType","label": "Company Type"}}]}},{"component": "Layout.column","props": {"md": 12,"lg": 8,"children": [{"component": "Control.switch","control": {"schemaPath": "companyType","message": {}},"props": {"id": "companyType","name": "companyType","label": "Company Type","moreText": "XYZ","labelPlacement": "end"}}]}}]}}]}}';

const data = JSON.parse(json);

const delChildInJSON = (input, childId) => {
  if (input.props) {
    if (input.props.id && input.props.id === childId) {
      console.log("found childId::" + childId);
      return {};
    }
    if (input.props.children && input.props.children.length) {
      const children = input.props.children.map(element => {
        return delChildInJSON(element, childId);
      });
      return { ...input, {...input.props, children: children }};
    }
  }
};

console.log(delChildInJSON(data, 'companyType'));

问题分析与修复方案

问题点

  1. 移除逻辑错误:找到目标组件时返回空对象,会导致父级children数组中残留空对象,而非彻底移除该组件。
  2. 结构破坏:扩展运算符使用错误,将input.props的属性直接平铺到根对象,打乱了原有的{ component: "...", props: {...} }层级。
  3. 边界处理缺失:无children的组件未返回原对象,导致部分结构丢失;未过滤无效元素。

修复后的函数

export const delChildInJSON = (input, childId) => {
  if (!input || typeof input !== 'object') return input;

  // 匹配到目标组件,返回null标记移除
  if (input.props?.id === childId) {
    console.log("found childId::" + childId);
    return null;
  }

  // 递归处理并过滤children
  if (input.props?.children && Array.isArray(input.props.children)) {
    const filteredChildren = input.props.children
      .map(child => delChildInJSON(child, childId))
      .filter(child => child !== null);

    // 保留原结构,更新props中的children
    return {
      ...input,
      props: {
        ...input.props,
        children: filteredChildren
      }
    };
  }

  // 无需处理,返回原对象
  return input;
};

修复说明

  • 标记移除:用null标记需要移除的组件,后续通过filter彻底从数组中删除。
  • 结构保留:严格维护原JSON的层级结构,仅更新props.children部分。
  • 边界处理:增加非对象输入的判断,避免递归出错;无children时返回原对象,保证结构完整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:49:56