Subhan Ahmed Subhan Ahmed - 6 months ago 43
PHP Question

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.

Answer

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);