问题
Good morning, given the below data structure (in JSON for ease of reading)
[
{
"parent": "root",
"active": "1",
"label": "Index",
"route": "/",
"children": [
{
"parent": "/",
"active": "1",
"label": "Products",
"route": "/products",
"children": [
{
"parent": "/products",
"active": "0",
"label": "Test",
"route": "/test"
}
]
}
]
},
{
"parent": "root",
"active": "1",
"label": "404",
"route": "/404"
},
{
"parent": "root",
"active": "1",
"label": "Login",
"route": "/login"
}
]
I am having major trouble returning from a function the following structure:
[
{
"parent": "root",
"active": "1",
"label": "Index",
"route": "/"
},
{
"parent": "/products",
"active": "0",
"label": "Test",
"route": "/test"
},
{
"parent": "/",
"active": "1",
"label": "Products",
"route": "/products"
},
{
"parent": "root",
"active": "1",
"label": "404",
"route": "/404"
},
{
"parent": "root",
"active": "1",
"label": "Login",
"route": "/login"
}
]
Essentially I want to recurse through all the children and populate a new array with every parent and child in the nested arrays, I have tried array_merge, RecursiveIteratorIterator, itterator_to_array, array_map but it always comes unstuck on the recursion. I managed to do it when the children were only one level deep but two or more simply breaks down.
Please help!
回答1:
Not very hard:
function flatten(array $array) {
$branch = [];
foreach ($array as $item) {
$children = [];
if (isset($item['children']) && is_array($item['children'])) {
$children = flatten($item['children']);
unset($item['children']);
}
$branch = array_merge($branch, [$item], $children);
}
return $branch;
}
回答2:
Easy-peasy
function flatten($items, &$r) {
foreach($items as $item) {
$c = isset($item->children) ? $item->children : null;
unset($item->children);
$r []= $item;
if($c)
flatten($c, $r);
}
}
flatten(json_decode($json), $r);
print_r($r);
This accumulates results in one single buffer, passed by reference. This is far more efficient than building a whole new array on each iteration, which is basically a variation of the Shlemiel the painter's algorithm.
If you prefer functional approach, you can use generators:
function flatten($items) {
foreach($items as $item) {
$c = isset($item->children) ? $item->children : [];
unset($item->children);
yield $item;
foreach(flatten($c) as $child)
yield $child;
}
}
foreach(flatten(json_decode($json)) as $item)
print_r($item);
来源:https://stackoverflow.com/questions/28393612/flattening-a-json-multi-depty-array-in-php