我需要解析看起来像这样的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
]
},
这是一个递归结构,其中每个元素都有mdfId
,mdfConcept
和children
个键。
假设我需要在此结构中找到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
密钥进行访问?
答案 0 :(得分:1)
JSON对象的一个令人尴尬的特点是,虽然每个children
成员都是" child"结构,顶层一个是对象本身,因此它是真正递归方法的障碍。
我们可以通过将源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);
}
}
}
}
答案 1 :(得分:0)
所以基本上我写了一个函数,它没有返回任何东西,而是从参数填充变量。
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;
}