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

如何从嵌套对象中根据属性移除指定元素(含子元素)

嵌套对象树移除指定type节点的问题解决

需求

从嵌套对象树中移除所有type属性为'green'的对象,若该对象包含children子元素则一并移除。

示例对象

const obj = {
  id: '01',
  children: [
    {
      id: '02',
      type: 'green',
      children: [
        {
          id: '03',
          type: 'black',
          children: [],
        },
        {
          id: '04',
          type: 'green',
          children: [
            {
              id: '05',
              type: 'white',
              children: [],
            }
          ],
        }
      ],
    },
    {
      id: '06',
      type: 'black',
      children: [
        {
          id: '07',
          type: 'green',
          children: [],
        },
        {
          id: '08',
          type: 'white',
          children: [
            {
              id: '09',
              type: 'green',
              children: [],
            }
          ],
        }
      ],
    },
  ]
}

预期结果

移除type为"green"的对象后:

const expectedObj = {
  id: '01',
  type: 'orange',
  children: [
    {
      id: '06',
      type: 'black',
      children: [
        {
          id: '08',
          type: 'white',
          children: [],
        }
      ],
    },
  ]
}

尝试的代码及问题

尝试的代码:

let match = false
const removeByType = (data, type) => {
  match = data.some(d => d.type == type)
  if (match) {
    data = data.filter(d => d.type !== type)
  } else {
    data.forEach(d => {
      d.children = removeByType(d.children, type)
    })
  }
  return data
}

let data = obj.children
console.dir(removeByType(data, 'black'), { depth: null })

执行后发现{ id: '03', type: 'black', children: [] }仍存在于对象树中,不符合预期。

问题分析

原代码的核心问题:

  1. 全局变量match在递归过程中会被覆盖,导致逻辑判断混乱;
  2. 逻辑分支完全错误:只要当前数组有匹配节点就直接过滤,但过滤后剩余节点的子节点没继续处理;只有数组完全无匹配节点时才处理子节点,逻辑倒置;
  3. 调用时传入的目标类型是'black',和需求的'green'不符。

正确解法

我们需要递归遍历每一层节点,先过滤当前层级的目标节点,再处理剩余节点的子元素:

const removeByType = (node, targetType) => {
  // 处理数组类型的节点集合
  if (Array.isArray(node)) {
    return node
      .filter(item => item.type !== targetType)
      .map(item => ({
        ...item,
        children: removeByType(item.children || [], targetType)
      }));
  }
  // 处理单个对象节点
  if (node.type === targetType) {
    return null;
  }
  return {
    ...node,
    children: removeByType(node.children || [], targetType)
  };
};

// 处理根对象并输出结果
const result = removeByType(obj, 'green');
console.dir(result, { depth: null });

代码说明

  • 区分数组和单个对象两种场景,分别处理;
  • 先过滤当前层级的目标节点,再递归处理剩余节点的子元素,确保所有嵌套层级的目标节点都被移除;
  • 采用纯函数方式,不修改原对象,返回全新的对象树;
  • 调用时传入正确的目标类型'green'。

执行这段代码后,所有type为'green'的节点(包括其下所有子节点)都会被移除,得到符合预期的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:40:44