如何在嵌套数组中找到目标对象前插入新对象
嵌套数组中指定对象前插入新元素失败问题解决
问题概述
需要在嵌套数组中找到指定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);
问题分析
- 核心逻辑错误:找到目标对象后,错误地尝试在该对象的
children中查找自身,结果必然返回-1,导致splice操作无效。实际应该在目标对象所在的父数组中找到其索引,再执行插入。 - 递归顺序错误:先递归子节点再判断当前节点,可能导致提前终止循环,且未正确传递找到目标的状态。
修正后的代码
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
相关产品推荐
相关产品推荐

