JavaScript:获取嵌套数组中指定对象索引并插入新对象
Hey there! The issue you're facing is that your current approach only checks the top level of the array, but since your data is a nested tree, you need a way to traverse all levels recursively to find the target node. Here's a step-by-step solution:
1. Recursive Function to Locate Nodes
First, let's create a helper function that searches the entire tree (including nested children) for a node by its Name property:
function findNodeByName(tree, targetName) { for (const node of tree) { // Check if current node matches the target if (node.Name === targetName) { return node; } // Recursively check children if they exist if (node.children && node.children.length > 0) { const foundNode = findNodeByName(node.children, targetName); if (foundNode) return foundNode; } } return null; // Return null if target isn't found }
2. Insert as a Child of a Target Node
To add a new node as a child of your target node (e.g., inserting under "Bani Cortes"), use this function:
function insertAsChild(tree, targetName, newNode) { const targetNode = findNodeByName(tree, targetName); if (targetNode) { // Ensure the target node has a children array (in case it doesn't exist yet) if (!targetNode.children) { targetNode.children = []; } // Add the new node to the children array targetNode.children.push(newNode); return true; // Success: node inserted } return false; // Failure: target node not found }
Example Usage
Inserting a new person under "Bani Cortes":
const newPerson = { "Name": "Maria Lopez", "nodetype": "person", "Country": "assets/img/aml-flag-3.png" }; insertAsChild(ruizTreeData, "Bani Cortes", newPerson);
3. Insert as a Sibling of a Target Node
If you want to add a new node as a sibling (e.g., making it a peer of "Checking"), we need to find the parent of the target node first. Here's how:
function findParentNode(tree, targetName) { for (const node of tree) { // Check if any child of the current node is the target if (node.children) { const isTargetChild = node.children.some(child => child.Name === targetName); if (isTargetChild) { return node; } // Recursively check children's children const foundParent = findParentNode(node.children, targetName); if (foundParent) return foundParent; } } return null; } function insertAsSibling(tree, targetName, newNode) { const parentNode = findParentNode(tree, targetName); if (parentNode) { parentNode.children.push(newNode); return true; } // Edge case: if target is a root node, add to the top-level array const targetNode = findNodeByName(tree, targetName); if (targetNode) { tree.push(newNode); return true; } return false; }
Example Usage
Inserting a new account as a sibling of "Checking":
const newAccount = { "Name": "Inserted object", "nodetype": "account", "Country": "assets/img/aml-flag-1.png" }; insertAsSibling(ruizTreeData, "Checking", newAccount);
Why Your Original Approach Didn't Work
Your initial code using map and indexOf only iterates over the first level of the ruizTreeData array. Since nested nodes are inside the children properties of parent nodes, those methods can't reach them. Recursion lets us dive into every level of the tree until we find the node we need.
Notes
- Both functions return
trueif the insertion was successful, so you can handle errors (e.g., show a message if the target node doesn't exist). - We ensure the
childrenarray exists before pushing to avoid errors if a node didn't have children initially.
内容的提问来源于stack exchange,提问作者hcharge

