繁体   English   中英

PHP递归JSON子级搜索

[英]PHP Recursive JSON Children Search

我需要解析如下所示的JSON:

{
    "mdfId":"282088127",
    "mdfConcept":"ME 3400EG-12CS-M Switch",
    "children":[
        {
            "mdfId":"007",
            "mdfConcept":"Another item",
            "children": [
                // many more here
            ]
        },
        {
             "mdfId":"008",
             "mdfConcept":"Another one",
             "children": [
                 {
                     "mdfId":"010",
                     "mdfConcept":"What I'm looking for!",
                     "children": [] // no children
                 }
             ]
        },
        // many more here
    ]
},

这是一种递归结构,其中每个元素都具有mdfIdmdfConceptchildren项键。

假设我需要在此结构中找到ID=010节点。 我不知道它位于哪一级(例如,它可以在顶层,也可以在下面几个children节点)。

我当前的方法是:

$mdfId = '010'; // what I'm loking for

foreach ($jsonResponse as $category) {
    while (true) {
        if ($category['mdfId'] == $mdfId) {
            // we found it!
            $categoryDevices[$mdfId] = $category['children'];
            break 2;
        }

        if (!empty($category['children'])) {
            next_cat:

            if (is_null($category['children'])) {
                break;
            }

            $category = array_shift($category['children']);
            continue;
        }

        if (empty($category['children'])) {
            goto next_cat;
        }
    }
}

但是目前的方法遗漏了一些情况。 如何优化此递归循环,以便它检查同一级别上的所有节点,并通过任意数量的children项键检查每个节点?

JSON对象的一个​​令人尴尬的特征是,尽管每个children成员都是“子”结构的数组, 但最顶层的对象是对象本身 ,因此这是真正递归方法的障碍。

我们可以通过将源JSON对象转换为与嵌套级别相同的结构来解决,即:

  • $jsonResponse作为原始对象
  • 使用['children' => $jsonResponse]代替

这样,它应该可以像这样工作:

$mdfId = '010'; // what I'm loking for

if ($result = look4id(['children' => $jsonResponse], $mdfId) {
    $categoryDevices[$mdfId] = $result;
}

function look4id($source, $id) {
    foreach ($source as $child) {
        if ($child['mdfId'] == $id) {
            return $source['children'];
        } else {
            if ($source['children']) {
                return look4id($source['children'], $id);
            }
        }
    }
}

因此,基本上,我编写了一个不返回任何内容,而是从参数中填充变量的函数。

function findRecursiveArrayNodeById($id, $array, &$node) {
    foreach ($array as $child) {
        if (isset($child['mdfId']) && $child['mdfId'] == $id) {
            $node = $child;
            return;
        }

        if (!empty($child['children'])) {
            findRecursiveArrayNodeById($id, $child['children'], $node);
        }
    }
}

用法如下:

$result = false;

findRecursiveArrayNodeById($mdfId, $category_json, $result);

if (!$result) {
    println("did not find {$mdfId}");
    continue;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM