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

如何在嵌套数组中找到目标对象前插入新对象

嵌套数组中指定对象前插入新元素失败问题解决

问题概述

需要在嵌套数组中找到指定name的对象,并在其前方插入新对象,但原有代码执行后数组无变化。需求是在name为Pumpkins的对象前插入{name: 'newname'}。

原始数据

const data = [
  {
    name: 'Fruit',
    children: [{ name: 'Apple' }, { name: 'Banana' }, { name: 'Fruit loops' }],
  },
  {
    name: 'Vegetables',
    children: [
      {
        name: 'Green',
        children: [{ name: 'Broccoli' }, { name: 'Brussels sprouts' }],
      },
      {
        name: 'Orange',
        children: [{ name: 'Pumpkins' }, { name: 'Carrots' }],
      },
    ],
  },
];

期望输出

const data = [
  {
    name: 'Fruit',
    children: [{ name: 'Apple' }, { name: 'Banana' }, { name: 'Fruit loops' }],
  },
  {
    name: 'Vegetables',
    children: [
      {
        name: 'Green',
        children: [{ name: 'Broccoli' }, { name: 'Brussels sprouts' }],
      },
      {
        name: 'Orange',
        children: [{ name: 'Pumpkins' },{name:'newname'}, { name: 'Carrots' }],
      },
    ],
  },
];

用户尝试的错误代码

function addObjectBefore(arr, targetName, newObj) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i].children) {
      addObjectBefore(arr[i].children, targetName, newObj); // Recursive call for nested children array
    }
    if (arr[i].name === targetName) {
      const targetIndex = arr[i]?.children?.findIndex(obj => obj.name === targetName);
      arr[i]?.children?.splice(targetIndex, 0, newObj); // Insert new object before the target
      break; // Stop the iteration once the target is found and object is inserted
    }
  }
}

// Given data
const data = [
  {
    name: 'Fruit',
    children: [{ name: 'Apple' }, { name: 'Banana' }, { name: 'Fruit loops' }],
  },
  {
    name: 'Vegetables',
    children: [
      {
        name: 'Green',
        children: [{ name: 'Broccoli' }, { name: 'Brussels sprouts' }],
      },
      {
        name: 'Orange',
        children: [{ name: 'Pumpkins' }, { name: 'Carrots' }],
      },
    ],
  },
];

// Call the function to add the new object
addObjectBefore(data, 'Pumpkins', { name: 'new name' });

// Output the modified data
console.log(data);

问题分析

  1. 核心逻辑错误:找到目标对象后,错误地尝试在该对象的children中查找自身,结果必然返回-1,导致splice操作无效。实际应该在目标对象所在的父数组中找到其索引,再执行插入。
  2. 递归顺序错误:先递归子节点再判断当前节点,可能导致提前终止循环,且未正确传递找到目标的状态。

修正后的代码

function addObjectBefore(arr, targetName, newObj) {
  for (let i = 0; i < arr.length; i++) {
    // 先检查当前节点是否为目标,找到则在父数组插入新对象
    if (arr[i].name === targetName) {
      arr.splice(i, 0, newObj);
      return true; // 返回true,终止递归链
    }
    // 递归处理子节点,若子节点中找到目标则直接返回
    if (arr[i].children && addObjectBefore(arr[i].children, targetName, newObj)) {
      return true;
    }
  }
  return false; // 未找到目标返回false
}

// 原始数据
const data = [
  {
    name: 'Fruit',
    children: [{ name: 'Apple' }, { name: 'Banana' }, { name: 'Fruit loops' }],
  },
  {
    name: 'Vegetables',
    children: [
      {
        name: 'Green',
        children: [{ name: 'Broccoli' }, { name: 'Brussels sprouts' }],
      },
      {
        name: 'Orange',
        children: [{ name: 'Pumpkins' }, { name: 'Carrots' }],
      },
    ],
  },
];

// 调用函数
addObjectBefore(data, 'Pumpkins', { name: 'newname' });

console.log(data);

代码说明

  • 遍历数组时优先检查当前元素是否为目标,找到后直接在当前数组(即目标的父数组)对应索引处插入新对象,返回true终止递归。
  • 递归处理子节点时,若子节点中找到目标,立即向上返回true,避免无效遍历。
  • 返回值用于传递“是否找到目标”的状态,确保找到后不再处理其他节点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 15:10:29