使用子元素的值将多维数组重新排序为层次结构

问题描述 投票:0回答:1

我需要通过使用单个数组中的group_parent_id作为参考,将平面多维数组转换为层次结构。

令人烦恼的是,我只能使用用户有权访问的组的子集合,因此,虽然Test group本身是孩子,但由于访问权限,它的父母实际上不在列表中。因此,从此用户角度来看,Test group将被视为根级别

可悲的是,这属于递归,这不是我的强项...

输入:

$arr = [
    [
        'group_id' => 5,
        'group_title' => 'Test group',
        'group_parent_id' => 2
    ],
    [
        'group_id' => 6,
        'group_title' => 'Second-level test group',
        'group_parent_id' => 5
    ],
    [
        'group_id' => 7,
        'group_title' => 'Third-level test group',
        'group_parent_id' => 6
    ],
    [
        'group_id' => 8,
        'group_title' => 'Other test group',
        'group_parent_id' => 1
    ],
    [
        'group_id' => 9,
        'group_title' => 'Second-level other test group',
        'group_parent_id' => 8
    ]
];

所需的输出:

$arr = [
    [
        'group_id' => 5,
        'group_title' => 'Test group',
        'group_parent_id' => 2,
        'subgroups' => [
            [
                'group_id' => 6,
                'group_title' => 'Second-level test group',
                'group_parent_id' => 5,
                'subgroups' => [
                    [
                        [
                            'group_id' => 7,
                            'group_title' => 'Third-level test group',
                            'group_parent_id' => 6
                        ]
                    ]
                ]
            ]
        ]
    ],
    [
        'group_id' => 8,
        'group_title' => 'Other test group',
        'group_parent_id' => 1,
        'subgroups' => [
            [
                'group_id' => 9,
                'group_title' => 'Second-level other test group',
                'group_parent_id' => 8
            ]
        ]
    ]
];

我尝试了一些不同的操作,但未能达到上述所需的期望结果:

function build_group_tree(array $groups, $group_ids = [])
{
    $output = [];

    foreach ($groups as $group) {
        if (in_array($group['group_parent_id'], $group_ids)) {
            $children = build_group_tree($groups, $group['group_id']);

            if ($children) {
                $group['subgroups'] = $children;
            }

            $output[] = $group;
        }
    }

    return $output;
}

build_group_tree($arr, array_column($arr, 'group_id));

这给了我部分结果,但不包括所有组。

感谢任何帮助。

php arrays multidimensional-array
1个回答
0
投票

一种方法是遍历数组,在输出数组中创建对每个group_id条目的引用列表,然后通过引用添加子项:

$output = array();
$group_ids = array();
foreach ($arr as $el) {
    $parent_id = $el['group_parent_id'];
    if (!isset($group_ids[$parent_id])) {
        // must be a top-level element
        $output[] = $el;
        // save a pointer
        $group_ids[$el['group_id']] = &$output[array_key_last($output)];
    }
    else {
        // already exists, $group_ids[$parent_id] points to the entry
        $parent = &$group_ids[$parent_id];
        if (!isset($parent['subgroups'])) {
            // no subgroups array, create one
            $parent['subgroups'] = array();
        }
        // add this entry to the subgroups
        $parent['subgroups'][] = $el;
        // save a pointer
        $group_ids[$el['group_id']] = &$parent['subgroups'][array_key_last($parent['subgroups'])];
    }
}
print_r($output);

输出:

Array
(
    [0] => Array
        (
            [group_id] => 5
            [group_title] => Test group
            [group_parent_id] => 2
            [subgroups] => Array
                (
                    [0] => Array
                        (
                            [group_id] => 6
                            [group_title] => Second-level test group
                            [group_parent_id] => 5
                            [subgroups] => Array
                                (
                                    [0] => Array
                                        (
                                            [group_id] => 7
                                            [group_title] => Third-level test group
                                            [group_parent_id] => 6
                                        )
                                )
                        )
                )
        )
    [1] => Array
        (
            [group_id] => 8
            [group_title] => Other test group
            [group_parent_id] => 1
            [subgroups] => Array
                (
                    [0] => Array
                        (
                            [group_id] => 9
                            [group_title] => Second-level other test group
                            [group_parent_id] => 8
                        )
                )
        )
)

Demo on 3v4l.org

注意,此代码使用array_key_last,它仅在7.3版中引入PHP。如果您使用的是较早版本,请使用array_key_last代替。

© www.soinside.com 2019 - 2024. All rights reserved.