Формирование древовидной структуры из HTML-элементов в массиве

Я вижу здесь реализацию с помощью рекурсивной функции, но..

Я десятки раз пытался создать эту функцию, но никак не могу понять логику, по которой она должна работать, хотя на первый взгляд это не должно быть так сложно. Кажется, я понимаю точки, в которых должен произойти выход из рекурсивной функции, но это мне ничего не дает.

Я хотел бы понять алгоритм, как он должен работать, на любом языке, возможно, хотя бы на словах, потому что до сих пор мне не удавалось "текстово" даже мысленно сформулировать, как должно выглядеть решение.

Я хочу реализовать функцию для генерации результирующего массива в нужном мне формате. Я подготовил данные для ввода и вывода, чтобы вам было понятнее, чего я хочу достичь.

ВХОДНЫЕ ДАННЫЕ

$input = ['h1', 'p', 'h2', 'p', 'p', 'h3', 'p', 'h2', 'p', 'h3', 'p', 'h1', 'p', 'h2', 'p', 'h3', 'p'];

ВЫХОДЯЩИЕ ДАННЫЕ

$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']
                    ]
                ]
            ]
        ]
    ]
];

Моя неработающая реализация:

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;
}

Ответы (0 шт):