PHP 重复分支递归 Children

PHP Branching Recursion With Repeating Children

我有一个平面结构,需要将其转换为嵌套 tree-like 结构。这与 other Stack Overflow questions 不同,因为 children 可以重复(即可以具有相同的 questionId 和 parentId)。我试图用分支递归来解决这个问题,但没有成功。

输入(平面数组):

[
    [
        'questionId' => 1,
        'name' => 'albumName',
        'parentId' => 0,
        'answer' => "Name of album",
    ],
    [
        'questionId' => 2,
        'name' => 'albumGenre',
        'parentId' => 0,
        'answer' => "album genre",
    ],
    [
        'questionId' => 3,
        'name' => 'trackStart',
        'parentId' => 0,
    ],
    [
        'questionId' => 4,
        'name' => 'trackName',
        'parentId' => 3,
        'answer' => "Track One",
    ],
    [
        'questionId' => 5,
        'name' => 'trackEnd',
        'parentId' => 3,
    ],
    [
        'questionId' => 3,
        'name' => 'trackStart',
        'parentId' => 0,
    ],
    [
        'questionId' => 4,
        'name' => 'trackName',
        'parentId' => 3,
        'answer' => "Track Two",
    ],
    [
        'questionId' => 6,
        'name' => 'artistStart',
        'parentId' => 3,
    ],
    [
        'questionId' => 7,
        'name' => 'artistName',
        'parentId' => 6,
        'answer' => "Artist Name",
    ],
    [
        'questionId' => 8,
        'name' => 'artistEnd',
        'parentId' => 6,
    ],
    [
        'questionId' => 5,
        'name' => 'trackEnd',
        'parentId' => 3,
    ],
    [
        'questionId' => 9,
        'name' => 'albumDate',
        'parentId' => 0,
        'answer' => "album Date",
    ]       
]

期望的输出(嵌套数组):

[
    'albumName' => 'Album Name',
    'albumGenre' => 'Album Genre',
    'trackStart' => [
        [
            'trackName' => 'Track One'
        ],
        [
            'trackName' => 'Track Two',
            'artistStart' => [
                [
                    'artistName' => 'Artist Name'
                ]
            ]
        ]
    ],
    'albumDate' => 'album Date'
]

您可以使用参考指针解决此问题:

$newArray = array();
$pointer[] = &$newArray;

foreach($arr as $ar) {

    if(stristr($ar['name'], "start")) {  // Start

        $pointer[] = &$pointer[count($pointer)-1][$ar['name']][];

    } else if(stristr($ar['name'], "end")) {  // End

        array_pop($pointer);

    } else {

        $pointer[count($pointer)-1][$ar['name']] = $ar['answer'];

    }
}

为了让它更快,你可以使用 stripos($ar['name'], "start") !== false;