PHP:如何将嵌套列表(数组)的所有键重命名为 'items'

PHP: How to rename all keys of a Nested List (Array) to 'items'

我需要 "reformat" 一些来自外部的数据 API 以便它与 Sencha touch 的嵌套列表模块一起工作。我无法更改该外部 API 的数据输出。这是我从 API:

获得的数据示例
$quest = array(
    'gastronomy' => [
        'restaurants' => [
            'italians' => [
                [
                    'title' => 'Al Castello',
                    'leaf' => true
                ],

                [
                    'title' => 'Italia',
                    'leaf' => true
                ]
            ],

            'asians' => [
                [
                    'title' => 'Gautam',
                    'leaf' => true
                ],

                [
                    'title' => 'Wok',
                    'leaf' => true
                ]
            ]
        ]
    ]
);

为了使其与 sencha touch 一起工作,数据在 "reformatting" 之后必须像这样使用 PHP 服务:

$result = array(
    'items' => [
        [
            'title' => 'gastronomy',
            'items' => [
                [
                    'title' => 'restaurants',
                    'items' => [
                        [
                            'title' => 'italians',
                            'items' => [
                                [
                                    'title' => 'Al Castello',
                                    'leaf' => true
                                ],

                                [
                                    'title' => 'Italia',
                                    'leaf' => true
                                ]
                            ]
                        ],

                        [
                            'title' => 'asians',
                            'items' => [
                                [
                                    'title' => 'Gautam',
                                    'leaf' => true
                                ],

                                [
                                    'title' => 'Wok',
                                    'leaf' => true
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
);

我能想到的方法都试过了,都没有成功。真正让我烦恼的是所有的键都必须重命名为项目。 (因为当我使用递归函数时,我很难访问更深的嵌套项)

还没有测试过,但似乎一个相当简单的递归函数应该可以处理它。

例如:

function parseApi($arr) {
    $result = array();
    foreach ($arr as $key => $value) {
        if (isset($value['leaf'])) {
            $result[] = $value;
        } else {
            $result[] = array(
                'title' => $key,
                'items' => parseApi($value)
            );
        }
    }

    return $result;
}

$result = array( 'items' => $parseApi($quest);

您需要一个递归函数,它需要能够区分关联数组和数字索引数组。

// from: 
function isAssoc($arr) { return array_keys($arr) !== range(0, count($arr) - 1); }

function itemize($foo) {
    $output = [];
    if( ! isAssoc($foo) ) {
        foreach( $foo as $value ) {
            if( is_array($value) ) {
                $output[] = itemize($value);
            } else {
                $output[] = $value;
            }
        }
    } else {
        foreach( $foo as $key => $value ) {
            if( is_array($value) ) {
                $output[] = [
                    'title' => $key,
                    'items' => itemize($value)
                ];
            } else {
                $output[$key] = $value;
            }
        }
    }
    return $output;
}

echo json_encode(itemize($quest), JSON_PRETTY_PRINT);

输出:

[
    {
        "title": "gastronomy",
        "items": [
            {
                "title": "restaurants",
                "items": [
                    {
                        "title": "italians",
                        "items": [
                            {
                                "title": "Al Castello",
                                "leaf": true
                            },
                            {
                                "title": "Italia",
                                "leaf": true
                            }
                        ]
                    },
                    {
                        "title": "asians",
                        "items": [
                            {
                                "title": "Gautam",
                                "leaf": true
                            },
                            {
                                "title": "Wok",
                                "leaf": true
                            }
                        ]
                    }
                ]
            }
        ]
    }
]