Gaz
Gaz

Reputation: 1648

Recursively search objects

I want to recursively search and replace elements in an array.

The array is tree based so looks like

Object
   Children
      Object type A
      Object type B
Object
   Children
      Object type A
Object

etc.

I want to be able to replace certain items with other items, so for example, I want to replace all entries in the array (at whatever depth level) of type A with an array of type B. But here's the catch: The newly replaced objects may also have children of type A that need to be replaced.

So far I've got

foreach ($nodes as &$node) {
    // Replace node?
    if ($node['type'] == 'RefObject') {
        $n = $this->site->get_node_where('id', $node['node_ref']);
        // Replace node
        $node = $this->site->get_node_where('object_id', $n['object_id']);
        // Get children
        $node['children'] = $this->site->get_descendants($node['lft'], $node['rgt']);
    }
}
return $nodes;

Which will replace the first level of RefObjects, but will not search the subsequently added children.

Upvotes: 2

Views: 8264

Answers (4)

Murat Colyaran
Murat Colyaran

Reputation: 2189

A working recursive function example here:

function multidimensionalArrayScan($arr, $pattern, &$result = []) : Array
    {

        foreach ($arr as $key => $value) {

            if (is_array($arr[$key])) {
                multidimensionalArrayScan($arr[$key], $pattern, $result);
                continue;
            }

            $match  = preg_match($pattern, $value);
            if (!empty($match))
                $result[$key] = $value;
        }

        return $result;
    }

Upvotes: 1

Aaron
Aaron

Reputation: 1

here's a recursive solution

function makeObject($array){
   $data = false;
   foreach($array as $key=>$value){
      if(is_array($value)){
        $value = makeObject($value);
      }
      $data -> {$key} = $value;
   }
   return $data;
}

thanks for getting me there!

Upvotes: 0

deceze
deceze

Reputation: 522135

Put your code into a function and call it again. Pseudocode:

function checkArray($array) {
    ...
    if (is_array($node)) {  // or whatever other criterium
        checkArray($node);  // same function
    }
}

The basics of recursion are to call the same code again...

Upvotes: 8

Josh
Josh

Reputation: 6322

you need to add this code into a function and call the function on the child nodes.

something like this (note the parseNodes function is called again inside the function):

function parseNodes($node) {

   foreach($nodes as &$node) {
    // Replace node?
    if($node['type'] == 'RefObject') {
        $n = $this->site->get_node_where('id', $node['node_ref']);
        // Replace node
        $node = $this->site->get_node_where('object_id', $n['object_id']);
        // Get children
        $node['children'] = parseNodes($this->site->get_descendants($node['lft'], $node['rgt']));
    }
   }
   return $nodes;
 }

Josh

Upvotes: 3

Related Questions