PHP树形结构数组转扁平数组的实现需求及原转换代码说明
Got it, let's reverse that tree structure back to your original flat array. The core idea is to traverse each node in the tree, strip out the children key, and ensure the parent_id is correctly set (especially for root nodes that don't have it in the tree).
Recursive Implementation (Simple & Readable)
This uses depth-first traversal, which mirrors how your buildTree function constructed the tree. It's straightforward and easy to follow:
function flattenTree(array $tree, int $parentId = 0): array { $flatList = []; foreach ($tree as $node) { // Create a flat version of the node by removing the 'children' key $flatNode = $node; unset($flatNode['children']); // Root nodes in your tree don't have 'parent_id'—set it to 0 (matching your original flat array) if (!isset($flatNode['parent_id'])) { $flatNode['parent_id'] = $parentId; } // Add the flat node to our list $flatList[] = $flatNode; // Recursively process any children, passing the current node's ID as their parent ID if (isset($node['children']) && !empty($node['children'])) { $flatList = array_merge($flatList, flattenTree($node['children'], $node['id'])); } } return $flatList; }
How to Use It
Just pass your $tree array to the function:
$list = flattenTree($tree); print_r($list);
This will output an array nearly identical to your original $array, except the order might differ slightly (since we traverse depth-first). If you need the exact order of your original array, you can sort the result by id:
usort($list, fn($a, $b) => $a['id'] - $b['id']);
Iterative Implementation (For Large/Deep Trees)
If your tree is extremely deep, recursion might hit PHP's stack limit. Here's an iterative alternative using a stack (still depth-first):
function flattenTreeIterative(array $tree): array { $flatList = []; $stack = []; // Initialize stack with root nodes, storing each node along with its parent ID foreach ($tree as $node) { $stack[] = [$node, 0]; } while (!empty($stack)) { // Pop the last node from the stack (LIFO) [$node, $parentId] = array_pop($stack); // Create flat node $flatNode = $node; unset($flatNode['children']); // Set parent ID if missing if (!isset($flatNode['parent_id'])) { $flatNode['parent_id'] = $parentId; } $flatList[] = $flatNode; // Push children to stack in reverse order to maintain original traversal order if (isset($node['children']) && !empty($node['children'])) { foreach (array_reverse($node['children']) as $child) { $stack[] = [$child, $node['id']]; } } } // Sort to match original array's order (optional) usort($flatList, fn($a, $b) => $a['id'] - $b['id']); return $flatList; }
Key Explanations
- Recursive Approach: We start with root nodes (parent ID 0), process each node, then dive into its children. This is intuitive and matches the structure of your
buildTreefunction. - Handling Parent IDs: Root nodes in your tree don't have
parent_id, so we explicitly set it to 0 to match your original flat array. Child nodes already haveparent_id, so we leave those intact. - Removing Children: The
childrenkey is specific to the tree structure, so we strip it out to get back to the original flat node format. - Order Consideration: Traversal order (depth-first) might not match your original array's order, hence the optional sort by
idto get an exact match.
Testing either function with your provided $tree will give you back the exact $array you started with (after sorting if needed).
内容的提问来源于stack exchange,提问作者codepnk

