I need to parse JSON which looks like this:
{
"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
]
},
This is a recursive structure in which every element has mdfId
, mdfConcept
and children
keys.
Say I need to find node with ID=010
within this structure. I don't know at which level it lies (eg it can be on top level, or several children
nodes below).
My current approach is:
$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;
}
}
}
But current approach misses some cases. How can I optimize this recursive loop so it checks all nodes on same level and each one accesible through any number of children
keys?
An embarrassing feature of your JSON object is that, while each children
member is an array of the "child" structure, the top level one is the object itself , so it's an obstacle to a really recursive approach.
We might workaround by turning the source JSON object into the same structure as nested levels, ie:
$jsonResponse
as original object ['children' => $jsonResponse]
instead This way, it should work with something like this:
$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);
}
}
}
}
So basically I wrote a function that didn't return anything, but rather populated a variable from arguments.
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);
}
}
}
Usage as follows:
$result = false;
findRecursiveArrayNodeById($mdfId, $category_json, $result);
if (!$result) {
println("did not find {$mdfId}");
continue;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.