'Recursion on subarrays with "child" key

I have array of arrays - tree structure of main menu. I try to find in this tree one node with needed slug and return this node with all it's childs. I write little recurcive function

<?php
$tree = '[{"id":1,"structure":1,"parent":0,"slug":"medicinskaya-ge","child":{"2":{"id":2,"structure":1.1,"parent":1,"slug":"dnk-diagnostika","child":{"3":{"id":3,"structure":"1.1.1","parent":2,"slug":"dnk-diagnostika","datafile":"ssz","template":"ssz"},"4":{"id":4,"structure":"1.1.2","parent":2,"slug":"dnk-diagnostika","child":{"5":{"id":5,"structure":"1.1.2.1","parent":4,"slug":"dnk-diagnostika"},"6":{"id":6,"structure":"1.1.2.2","parent":4,"slug":"testirovanie-ge"},"7":{"id":7,"structure":"1.1.2.3","parent":4,"slug":"dnk-diagnostika"}}},"8":{"id":8,"structure":"1.1.3","parent":2,"slug":"dnk-diagnostika"},"9":{"id":9,"structure":"1.1.4","parent":2,"slug":"texnologiya-kol"}}}}}]';
$tree = json_decode($tree, true);


function getSlugData(string $slug, array $data)
{
    foreach ($data as $row) {
        if ($row['slug'] == $slug) {
            return $row;
        }
        if (isset($row['child'])) {
            //return $this->getSlugData($slug, $row['child']);
        }
    }

    return [];
}


$result = getSlugData('testirovanie-ge', $tree);
print_r($result);

But as a result I have an empty array. If I print_r($row) when $row['slug'] == $slug - It appears on screen.

if ($row['slug'] == $slug) {
    exit(print_r($row));
    return $row;
}

What's my mistake?



Solution 1:[1]

In the recursive function, you must not break the loop early unless you find your slug match. If a non-slug-match has a child element, you must iterate it and potentially pass up a match in subsequent recursive calls.

Code: (Demo)

function getSlugData(string $slug, array $data): array
{
    foreach ($data as $row) {
        if ($row['slug'] === $slug) {
            return $row;
        }
        if (isset($row['child'])) {
            $deeper = getSlugData($slug, $row['child']);
            if ($deeper) {
                return $deeper;
            }
        }
    }
    return [];
}

P.s. you aren't calling a class method, so $this-> is inappropriate.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mickmackusa