简体   繁体   中英

PHP push a value to an array during recursive search

    $menus = [
        0 => [
            'id' => 'home',
            'title' => 'Home',
            'url' => '/display/home',
            'children' => [],
            'parent' => null
        ],
        1 => [
            'id' => 'nodes',
            'title' => 'Nodes',
            'url' => 'nodes/index',
            'children' => [
                0 => [
                    'id' => 'addNode',
                    'title' => 'Add Node',
                    'url' => '/nodes/add',
                    'children' => [],
                    'parent' => "nodes"
                ],
                1 => [
                    'id' => 'editNode',
                    'title' => 'Edit Node',
                    'url' => '/nodes/edit',
                    'children' => [],
                    'parent' => 'nodes'
                ],
                2 => [
                    'id' => 'deleteNode',
                    'title' => 'Delete Node',
                    'url' => '/nodes/delete',
                    'children' => [
                        0 => [
                            'id' => 'deleteMultipleNodes',
                            'title' => 'Delete Multiple Nodes',
                            'url' => '/nodes/deleteall',
                            'children' => [
                                0 => [
                                    'id' => 'deleteMultipleSelectedNodes',
                                    'title' => 'Delete Multiple Selected Nodes',
                                    'url' => '/nodes/deleteallselected',
                                    'children' => [],
                                    'parent' => 'deleteMultipleNodes'
                                ]
                            ],
                            'parent' => 'deleteNode'
                        ]
                    ],
                    'parent' => 'nodes'
                ]

            ],
            'parent' => null
        ]
    ];

Assuming I have this array. What i want is to recursively search this array for an "id" and if found push a new children to the children array of that element.

I've tried it via different ways, I've also tried to use RecursiveArrayIterator to traverse the array, but the problem is how can i push value to that index of the array when found while traversing.

For Example here is a code from one of my tries:

private function traverseArray($array)
{

    $child = [
        'id' => 'deleteMultipleNotSelectedNodes',
        'title' => 'Delete Multiple Not Selected Nodes',
        'url' => '/nodes/deletenotselected',
        'children' => [],
        'parent' => 'deleteMultipleNodes'
    ];
    foreach($array as $key=>$value)
    {
        if(is_array($value))
        {
            $this->traverseArray($value);
        }
        if($key == "id" && $value == "deleteMultipleNodes") 
        {
            array_push($array["children"], $child); // This part is confusing me, How to add the child on this index where the id is found. 
        }
    }
}

Any help on how to do such thing in an efficient way would save my days.

Here it's how it would work without using $this and fixing bugs in comparing $value instead assigning anything to value.

Please note the difference with &$array and &$value, which are references, so it would change the original data instead of copying it into new variables.

<?php
$menus = [
        0 => [
            'id' => 'home',
            'title' => 'Home',
            'url' => '/display/home',
            'children' => [],
            'parent' => null
        ],
        1 => [
            'id' => 'nodes',
            'title' => 'Nodes',
            'url' => 'nodes/index',
            'children' => [
                0 => [
                    'id' => 'addNode',
                    'title' => 'Add Node',
                    'url' => '/nodes/add',
                    'children' => [],
                    'parent' => "nodes"
                ],
                1 => [
                    'id' => 'editNode',
                    'title' => 'Edit Node',
                    'url' => '/nodes/edit',
                    'children' => [],
                    'parent' => 'nodes'
                ],
                2 => [
                    'id' => 'deleteNode',
                    'title' => 'Delete Node',
                    'url' => '/nodes/delete',
                    'children' => [
                        0 => [
                            'id' => 'deleteMultipleNodes',
                            'title' => 'Delete Multiple Nodes',
                            'url' => '/nodes/deleteall',
                            'children' => [
                                0 => [
                                    'id' => 'deleteMultipleSelectedNodes',
                                    'title' => 'Delete Multiple Selected Nodes',
                                    'url' => '/nodes/deleteallselected',
                                    'children' => [],
                                    'parent' => 'deleteMultipleNodes'
                                ]
                            ],
                            'parent' => 'deleteNode'
                        ]
                    ],
                    'parent' => 'nodes'
                ]

            ],
            'parent' => null
        ]
    ];

function traverseArray(&$array)
{
    $child = [
        'id' => 'deleteMultipleNotSelectedNodes',
        'title' => 'Delete Multiple Not Selected Nodes',
        'url' => '/nodes/deletenotselected',
        'children' => [],
        'parent' => 'deleteMultipleNodes'
    ];
    foreach($array as $key=>&$value)
    {
        if(is_array($value))
        {
            traverseArray($value);
        }
        if($key == "id" && $value == "deleteMultipleNodes") 
        {
            array_push($array["children"], $child); 
        }
    }
}

echo "=== before \n";
var_export($menus);
echo "\n\n";
traverseArray($menus);
echo "=== after \n";
var_export($menus);

Maybe this will help you. array_walk_recursive will walk through all elements. And callback function can receive $value by reference. So, when you modify $value this will modify item in source array.

array_walk_recursive($array, function (&$value, $key) {
    if(is_array($value) && $value['id'] === "deleteMultipleNodes") {
        $child = [
            'id' => 'deleteMultipleNotSelectedNodes',
            'title' => 'Delete Multiple Not Selected Nodes',
            'url' => '/nodes/deletenotselected',
            'children' => [],
            'parent' => 'deleteMultipleNodes'
        ];
        array_push($value['children'], $child);
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM