使用 "child" 键对子数组进行递归

Recursion on subarrays with "child" key

我有数组的数组 - 主菜单的树结构。 我试图在这棵树中找到一个需要 slug 和 return 这个节点及其所有子节点的节点。 我写了一点递归函数

<?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);

但结果我得到了一个空数组。如果我 print_r($row)$row['slug'] == $slug - 它出现在屏幕上。

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

我的错误是什么?

在编程中,递归是一种有用且强大的机制,它允许函数直接或间接调用自身,也就是说,如果函数至少包含一个对自身的显式或隐式调用,则称该函数是递归的。

我稍微修改了你的代码,得到了下面的解决方案。

$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);

//print_r($tree);
//die();

function getSlugData(string $slug, array $data, string $key = 'slug')
{
    $result = [];
    foreach ($data as $row) {
        // Checks if the key exists and is the desired value for that key in the array
        if (isset($row[$key]) && $row[$key] === $slug) {
            return $row;
        }

        // If it is an array, apply recursion by calling getSlugData again
        if (is_array($row)) {
            $result = getSlugData($slug, $row, $key);
            if ($result !== []) {
                return $result;
            }
        }
    }

    return $result;
}

print_r(getSlugData('testirovanie-ge', $tree));
print_r(getSlugData('texnologiya-kol', $tree));
print_r(getSlugData('nothing-here', $tree));
die();

在递归函数中,除非找到匹配项,否则不得提前中断循环。如果 non-slug-match 有子元素,您必须迭代它并可能在后续递归调用中传递匹配。

代码:(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。您没有调用 class 方法,因此 $this-> 不合适。