如何在JavaScript中扁平化含children的对象数组?Lodash尝试无效
children property? I have the following data structure:
const array = [ { name: 'bar', children: [ { name: 'foo', children: [ { name: 'baz123' }, { name: 'baz' } ] } ] }, { name: 'shallowKey' }, { name: 'abc' } ];I want to flatten it to:
[ { name: 'bar' }, { name: 'foo' }, { name: 'baz123' }, { name: 'baz' }, { name: 'shallowKey' }, { name: 'abc' } ];I tried using Lodash but it didn't work. Are there any other implementation methods? Thanks.
Great question! Flattening nested arrays of objects with a children property is a common task, and there are several reliable ways to do this — whether you want a recursive, functional, or iterative approach. Let's break them down, plus fix that Lodash method you tried:
Solution 1: Simple Recursive Function
This is the most intuitive approach for nested structures. We'll iterate over each item, extract the relevant properties (excluding children), then recursively process any nested children and add those results to our final array.
function flattenNestedArray(arr) { let result = []; arr.forEach(item => { // Pull out everything except the 'children' property const { children, ...itemWithoutChildren } = item; result.push(itemWithoutChildren); // If the item has children, recursively flatten them and append to the result if (children && children.length > 0) { result = result.concat(flattenNestedArray(children)); } }); return result; } // Test it out: const flattened = flattenNestedArray(array); console.log(flattened); // Matches your desired output!
Solution 2: Functional Approach with flatMap
If you prefer a more concise, functional style, Array.flatMap is perfect here. It combines mapping and flattening in one step, and we can pair it with recursion to handle nested children:
const flattenNestedArray = arr => arr.flatMap(item => { const { children, ...rest } = item; // Return the current item plus recursively flattened children (if any) return children ? [rest, ...flattenNestedArray(children)] : [rest]; }); // Usage: const flattened = flattenNestedArray(array); console.log(flattened);
Solution 3: Iterative (Non-Recursive) Approach
For extremely deep nested structures, recursion could hit stack limits. An iterative method using a stack avoids this issue:
function flattenNestedArray(arr) { const result = []; const stack = [...arr]; // Start with all top-level items while (stack.length > 0) { const item = stack.pop(); const { children, ...rest } = item; result.push(rest); // Push children to the stack in reverse order to preserve original sequence if (children && children.length > 0) { stack.push(...[...children].reverse()); } } // Reverse the result to get back the original order (since we popped from the stack) return result.reverse(); } // Usage: const flattened = flattenNestedArray(array); console.log(flattened);
Fixing Your Lodash Attempt
The reason your Lodash try didn't work is likely because you used generic flatten methods that don't know to target the children property. Use _.flatMapDeep with a custom iteratee to make it work:
const flattened = _.flatMapDeep(array, item => { const { children, ...rest } = item; return children ? [rest, ...children] : [rest]; });
This will correctly traverse all nested children levels and produce your desired flattened array.
内容的提问来源于stack exchange,提问作者aspiring_dev

