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

遍历嵌套对象数组更新指定ID状态失效问题排查

嵌套对象数组修改指定节点状态后返回原数组的问题

需求与问题

  • 需求:遍历对象数组,在深层嵌套对象中查找指定ID,找到后将该节点的status修改为Activated,并返回完整的更新后数组。
  • 问题:当前代码能进入匹配ID的if语句,但最终返回的仍是原输入数组,未得到更新结果。

原代码

TypeScript版本

export function findChild(array: any, id: string): array {
    return array.map((node) => {
        if (node.id === id) {
            return { ...node, status: 'Activated' };
        } else {
            if (node.children?.length) {
                findChild(node.children, id);
            }
        }
        return node;
    });
}

JavaScript版本及输入示例

function findChild(array, id) {
  return array.map((node) => {
    if (node.id === id) {
      return { ...node, status: 'Activated' };
    } else {
      if (node.children?.length) {
        findChild(node.children, id);
      }
    }
    return node;
  });
}

// 输入示例
let input = [{
    id: '1',
    amt: '30',
    status: 'Active',
    children: [{
        id: 'SG2',
        amt: '305',
        status: 'Active',
      },
      {
        id: '5',
        amt: '30',
        status: 'Active',
        children: [],
      },
    ],
  },
  {
    id: '6',
    amt: '307',
    status: 'Active',
    children: [],
  },
  {
    id: '7',
    amt: '40',
    status: 'Inactive',
    children: [{
      id: '7',
      amt: '40',
      status: 'Inactive',
      children: []
    }],
  },
  {
    id: '8',
    amt: '100',
    status: 'Dead',
    children: [],
  },
];

// 原调用方式
findChild(input,7)
console.log(input)

问题根源

  1. 递归结果未复用:递归调用findChild(node.children, id)时,只是执行了函数但没有将返回的更新后子数组赋值回当前节点,原节点的children还是旧的引用,导致上层节点无法感知子树的修改。
  2. 未接收函数返回值:原代码直接打印原input数组,但该函数是纯函数(不会修改原数组,而是返回新数组),必须接收返回值才能拿到更新后的结果。

修复后的代码

TypeScript版本

export function findChild(array: any[], id: string): any[] {
    return array.map((node) => {
        // 匹配到目标ID,返回修改status后的新节点
        if (node.id === id) {
            return { ...node, status: 'Activated' };
        }
        // 递归处理子节点,拿到更新后的子数组
        const updatedChildren = node.children?.length ? findChild(node.children, id) : node.children;
        // 返回包含更新后子节点的新节点
        return { ...node, children: updatedChildren };
    });
}

JavaScript版本

function findChild(array, id) {
  return array.map((node) => {
    if (node.id === id) {
      return { ...node, status: 'Activated' };
    }
    const updatedChildren = node.children?.length ? findChild(node.children, id) : node.children;
    return { ...node, children: updatedChildren };
  });
}

正确使用方式

// 接收函数返回的更新后数组
const updatedInput = findChild(input, '7');
// 打印更新后的结果
console.log(updatedInput);

修复说明

  • 递归处理子节点时,将返回的更新后子数组赋值给updatedChildren,并通过对象展开运算符创建新节点,替换原节点的children,确保整个树的修改能向上传递。
  • 函数保持纯函数特性,不修改原数组,所有修改都基于新创建的对象,避免副作用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:20:21