I see an implementation here via a recursive function, but..
I've tried dozens of times to compose this function, but I can't get my head around the logic by which it should work, although at first glance it shouldn't be so difficult. I seem to understand the points where the exit from the recursive function should occur, but it doesn't give me anything.
I would like to understand the algorithm how it should work, in any language, perhaps at least in words, because so far I have not been able to "text" even mentally formulate what the solution should look like.
I want to implement a function to generate the resulting array in the format I need.I have prepared the data, input and output, so that it is clearer to you what I want to achieve.
INPUT
$input = ['h1', 'p', 'h2', 'p', 'p', 'h3', 'p', 'h2', 'p', 'h3', 'p', 'h1', 'p', 'h2', 'p', 'h3', 'p'];
OUTPUT
$output = [ ['title' => 'h1','descriptions' => ['p'],'childrens' => [ ['title' => 'h2','descriptions' => ['p', 'p'],'childrens' => [ ['title' => 'h3','descriptions' => ['p'], ], ] ], ['title' => 'h2','descriptions' => ['p'],'childrens' => [ ['title' => 'h3','descriptions' => ['p'] ] ] ] ] ], ['title' => 'h1','descriptions' => ['p'],'childrens' => [ ['title' => 'h2','descriptions' => ['p'],'childrens' => [ ['title' => 'h3','descriptions' => ['p'] ] ] ] ] ]];
my (not working) implementation:
function parseDOM(array $inputArray): array { $output = []; $position = 0; $domElementsQuantity = count($inputArray); $parentTagLvl = 0; function getCurrentTagLvl(string $node): bool|int { return match ($node) {'h1' => 1,'h2' => 2,'h3' => 3,'h4' => 4,'h5' => 5,'h6' => 6, default => false, }; } function recursiveCreateTree(array $inputArray, int &$offsetIndex, $parentTagLvl) { $tree = []; $arrayItemsQuantity = count($inputArray); while ($offsetIndex <= $arrayItemsQuantity) { $currentNode = $inputArray[$offsetIndex]; $currentTagLvl = getCurrentTagLvl($currentNode); if ($currentTagLvl !== false && $currentTagLvl < $parentTagLvl) { return $tree; } if ($currentTagLvl === false) { $tree['descriptions'][] = $currentNode; } else { $tree['title'] = $currentNode; $tree['childrens'] = recursiveCreateTree($inputArray, $offsetIndex, $currentTagLvl); } $offsetIndex++; } return $tree; } while ($position <= $domElementsQuantity) { $currentNode = $inputArray[$position]; $currentTagLvl = getCurrentTagLvl($currentNode); if ($currentTagLvl === false) { } else { if ($currentTagLvl > $parentTagLvl) { } else { $parentTagLvl = $currentTagLvl - 1; } } } return $output;}
To display the results:
echo '<pre>';print_r(parseDOM($input));