在PHP中展平JSON多depty数组

时间:2015-02-08 11:55:10

标签: php arrays json multidimensional-array flatten

早上好,给出以下数据结构(为了便于阅读,使用JSON)

[
{
    "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"
    }
]

我遇到了从以下结构函数返回的主要问题:

[
{
    "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"
}
]

基本上我想通过所有子进行递归并在嵌套数组中为每个父和子填充一个新数组,我已经尝试过array_merge,RecursiveIteratorIterator,itterator_to_array,array_map但它总是在递归时不会出现。当孩子只有一层深,但两个或两个以上简单地崩溃时,我设法做到了。

请帮忙!

2 个答案:

答案 0 :(得分:3)

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

这会将结果累积到一个缓冲区中,通过引用传递。这比在每次迭代上构建一个全新数组要有效得多,这基本上是Shlemiel the painter's algorithm的变体。

如果您更喜欢功能方法,可以使用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);

答案 1 :(得分:1)

不是很难:

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;
}