Search code examples
phparraysrecursionmultidimensional-array

How to reformat a nested array?


I have a stored unlimited nested levels array with unwanted extra data.

$arr = array(
    array(
        'name' => 'item1',
        'level' => 0,
        'extra_key' => 'some_data',
        'children' => array(
            'name' => 'sub-item1',
            'level' => 1,
            'extra_key' => 'some_data',
            'children' => array(
                'name' => 'sub-sub-item1',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
            array(
                'name' => 'sub-sub2-item1',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
        )
    ),
    array(
        'name' => 'item2',
        'level' => 0,
        'extra_key' => 'some_data',
        'children' => array(
            'name' => 'sub-item2',
            'level' => 2,
            'extra_key' => 'some_data',
            'children' => array(
                'name' => 'sub-sub-item2',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
            array(
                'name' => 'sub-sub2-item2',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
        )
    ),
    array(
        'name' => 'item3',
        'level' => 0,
        'extra_key' => 'some_data',
        'children' => array(
            'name' => 'sub-item3',
            'level' => 1,
            'extra_key' => 'some_data',
            'children' => array(
                'name' => 'sub-sub-item3',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
            array(
                'name' => 'sub-sub2-item3',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
        )
    ),
);

Expected output array:

$arr = array(
    array(
        'name' => 'item1',
        'nodes' => array(
            'name' => 'sub-item1',
            'nodes' => array(
                'name' => 'sub-sub-item1',
                'nodes' => array()
            ),
            array(
                'name' => 'sub-sub2-item1',
                'nodes' => array()
            ),
        )
    ),
    array(
        'name' => 'item2',
        'nodes' => array(
            'name' => 'sub-item2',
            'nodes' => array(
                'name' => 'sub-sub-item2',
                'nodes' => array()
            ),
            array(
                'name' => 'sub-sub2-item2',
                'nodes' => array()
            ),
        )
    ),
    array(
        'name' => 'item3',
        'nodes' => array(
            'name' => 'sub-item3',
            'nodes' => array(
                'name' => 'sub-sub-item3',
                'nodes' => array()
            ),
            array(
                'name' => 'sub-sub2-item3',
                'nodes' => array()
            ),
        )
    )
);

I want to remove unwanted keys like level , extra_key from all levels and i want also to change the name of the key children to nodes then reproduce the same array with the same structure with the new format.

How can i achieve that?

I tried to do it by recursive function but i failed to reproduce the same structrue


Solution

  • Your structure doesn't make sense, probably because of that you was unable to write recursive function. If it is possible to change structure, I would suggest this one (with reformat function implementation):

    <?php
    
    $actual = array(
        array(
            'name' => 'item1',
            'level' => 0,
            'extra_key' => 'some_data',
            'children' => array(
                array(
                    'name' => 'sub-item1',
                    'level' => 1,
                    'extra_key' => 'some_data',
                    'children' => array(
                        array(
                            'name' => 'sub-sub-item1',
                            'level' => 2,
                            'extra_key' => 'some_data',
                            'children' => array()
                        ),
                        array(
                            'name' => 'sub-sub2-item1',
                            'level' => 2,
                            'extra_key' => 'some_data',
                            'children' => array()
                        ),
                    )
                ),
            )
        ),
    );
    
    $expected = array(
        array(
            'name' => 'item1',
            'nodes' => array(
                array(
                    'name' => 'sub-item1',
                    'nodes' => array(
                        array(
                            'name' => 'sub-sub-item1',
                            'nodes' => array()
                        ),
                        array(
                            'name' => 'sub-sub2-item1',
                            'nodes' => array()
                        ),
                    ),
                ),
            )
        ),
    );
    
    function change_array($original)
    {
        return array_map('change_node', $original);
    }
    
    function change_node($node)
    {
        return [
            'name' => $node['name'],
            'nodes' => array_map('change_node', $node['children']),
        ];
    }
    
    var_dump($expected === change_array($actual));