Search code examples
phpmultidimensional-arrayphp-5.5breadth-first-search

How to traverse php array with bfs with modifications


Hell0 coders. I try to traverse multiarray with BFS and modify array. How to do this? My snippet with bfs is in the section below. It itterates the array, but I can't save changes (I added some comments in code).

   /**
     * @param array $tree
     * @param callable $callable
     * @return array
     */
    function bfs($tree, $callable)
    {
        $mn = function($item) use($callable) {
            // preserve items for array traverse
            return $callable($item) + ['items' => $item['items']];
        };
        $queue = new \SplQueue();
        $start = $tree[0];
        $queue->enqueue($start);
        $visited = [$start['id']];
        while ($queue->count()) {
            $node = $queue->dequeue();
            foreach ($node['items'] as $item) {
                if (!in_array($item['id'], $visited)) {
                    $visited[] = $item['id'];
                    $queue->enqueue($item);
                    $item = $mn($item); // I need save modifications here
                }
            }
            $node = $mn($node); // I need save modifications here
        }
        return $tree;
    }

My simplified input is:

[
    0 => [
        'id' => '1'
        'left_id' => '1'
        'right_id' => '8'
        'depth' => '0'
        'name' => 'Page level 1'
        'items' => [
            0 => [
                'id' => '4'
                'left_id' => '2'
                'right_id' => '5'
                'depth' => '1'
                'name' => 'Page level 1.1'
                'items' => []
            ]
        ]
    ]
]

My output needs to be smth like this:

[
    0 => [
        'label' => 'Page level 1'
        'items' => [
            0 => [
                'label' => 'Page level 1.1'
                'items' => []
            ]
        ]
    ]
]

P.S. The main problem is to pop/push element to array.

<? 
    $start = '23';
    $queue = [];
    // array_push($queue, &$start); causes Fatal error
    array_push($queue, $start); 
    $start2 = array_pop($queue); // I need get reference to $start
    $start2 = '24';
    echo $start; // needed result shoud be 24, i.e. to change $start by reference

Solution

  • This works

    <?
        public function handleTree(&$array, $callback)
        {
            foreach ($array as &$item) {
                handleTree($item['items'], $callback);
                $item = $callback($item) + ['items' => $item['items']];
            }
        }