递归遍历节点子元素:如何扁平化含嵌套children的数组对象
Hey there! Let’s work through this nested node flattening problem— I’ve dealt with this exact scenario more times than I can count, so I know how frustrating it is when your first attempts don’t land. Let’s break down a solid recursive solution, plus an iterative fallback for deep nesting cases.
First, let’s assume your data looks something like this (super common structure for nested nodes):
const nestedNodes = [ { id: 1, label: "Top Level 1", children: [ { id: 2, label: "Second Level 1a" }, { id: 3, label: "Second Level 1b", children: [ { id: 4, label: "Third Level 1b1" }, { id: 5, label: "Third Level 1b2", children: [{ id: 6, label: "Fourth Level 1b2a" }] } ] } ] }, { id: 7, label: "Top Level 2" } ];
Recursive Solution (Clean & Readable)
This is the most straightforward approach for most cases. We’ll write a function that traverses each node, adds it to our result array, then recursively processes any nested children arrays.
function flattenNestedNodes(nodes) { let flattened = []; nodes.forEach(node => { // Add the current node to the result. If you don't want to keep the `children` property, use destructuring: // const { children, ...nodeWithoutChildren } = node; // flattened.push(nodeWithoutChildren); flattened.push(node); // Check if the node has a valid children array before recursing if (node.children && Array.isArray(node.children)) { flattened = flattened.concat(flattenNestedNodes(node.children)); } }); return flattened; } // Usage: const flatNodes = flattenNestedNodes(nestedNodes); console.log(flatNodes); // All nodes in a single-level array
How this works:
- We start with an empty result array (
flattened). - For every node in the input array, we first add the node itself to the result.
- If the node has a
childrenproperty that’s an actual array, we recursively call our function on those children, then concatenate the returned flattened array to our main result. - The check for
Array.isArray(node.children)prevents errors if a node has achildrenvalue that’s null, undefined, or a non-array.
Iterative Solution (For Deeply Nested Data)
If you’re dealing with extremely deep nesting (like hundreds of levels), recursion might hit JavaScript’s call stack limit. In that case, an iterative approach using a stack is safer:
function flattenNodesIterative(nodes) { const stack = [...nodes]; const flattened = []; while (stack.length > 0) { const currentNode = stack.pop(); flattened.push(currentNode); // Reverse the children before pushing to stack to maintain original order if (currentNode.children && Array.isArray(currentNode.children)) { stack.push(...[...currentNode.children].reverse()); } } // Reverse the final array to match the original traversal order return flattened.reverse(); }
Why this works:
- We use a stack to mimic the call stack from recursion. We start by pushing all top-level nodes into the stack.
- We pop a node from the stack, add it to our result, then push its children (in reversed order) back into the stack. Reversing ensures we process children in the same order as the recursive method.
- Finally, we reverse the result array to get the same order as our recursive solution.
Quick Tips
- If your nested nodes use a different property name instead of
children(likesubNodesoritems), just replace every instance ofnode.childrenwith your target property. - If you need to filter nodes during flattening (e.g., only include nodes with a specific
type), add anifcheck before pushing the node to the result array.
内容的提问来源于stack exchange,提问作者Thabo

