简体   繁体   中英

Recursive traversal of object

I'm having trouble writing a recursive function to traverse this hierarchical structure

    object(stdClass)#290 (6) {
      ["category_id"]=>
      int(1)
      ["parent_id"]=>
      int(0)
      ["name"]=>
      string(4) "Root"
      ["position"]=>
      int(0)
      ["level"]=>
      int(0)
      ["children"]=>
      array(2) {
        [0]=>
        object(stdClass)#571 (7) {
          ["category_id"]=>
          int(2)
          ["parent_id"]=>
          int(1)
          ["name"]=>
          string(18) "Root MySite.com"
          ["is_active"]=>
          int(0)
          ["position"]=>
          int(0)
          ["level"]=>
          int(1)
          ["children"]=>
          array(11) {
            [0]=>
            object(stdClass)#570 (7) {
              ["category_id"]=>
              int(15)
              ["parent_id"]=>
              int(2)
              ["name"]=>
              string(9) "Widgets"
              ["is_active"]=>
              int(1)
              ["position"]=>
              int(68)
              ["level"]=>
              int(2)
              ["children"]=>
              array(19) {
                [0]=>
                object(stdClass)#566 (7) {
                  ["category_id"]=>
                  int(24)
                  ["parent_id"]=>
                  int(15)
                  ["name"]=>
                  string(16) "Blue widgets"
                  ["is_active"]=>
                  int(1)
                  ["position"]=>
                  int(68)
                  ["level"]=>
                  int(3)
                  ["children"]=>
                  array(0) {
                  }
                }

<snip....>

As you can see this nested set can go on forever.. .

What I want to return is something like this

$categories("Root" => array("Root MySite.com" => array("Widgets" => array("Blue Widgets",...))))

[EDIT] : pasting my starting point for my recursive function that will simply "flatten out" an arry or object. I would think i could modify this to make get the data structure I'm looking for but haven't been able to get it quite right.

    function array_flatten($array, $return) 
{


  // `foreach` can also iterate through object properties like this 
  foreach($array as $key => $value)
  {
    if(is_object($value))
    {
      // cast objects as an array
      $value = (array) $value;
    }
    if(is_array($value))
    {
      $return = array_flatten($value,$return);
    }
    else
    {
      if($value)
      {
        $return[] = $value;
      }
    }

  }
  return $return;
}

The question is I can't quite figure out to build the structure I'm looking for recursively, or maybe there is a more elegant php way to do this?

Try this

function run($o) {
    $return = array();
    foreach ($o->children as $child) {
        $return[$child->name] = run($child);
    }

    return empty($return) ? null : $return;
}

I don't have time to write a working answer, but here's some pseudo code to do it (half PHP, half JS)

This would create a flattened version of the tree by removing the children property of each element in your list.

$flattened = array();

function addElement(&$flattened, $list) {
    for ($element in $list) {
        $children = $element->children;
        delete $element->children;
        $flattened[] = $element;
        if ($children) {
            addElements($flattened, $children)
        }
    }
}
addElements($flattened, $treeHierarchy);

deep_order object or assoc_array

namespace a_nsp
class object_utils{

   static function deep_order($IN, $desc = NULL) { // object or assoc_array
       $O = new \stdClass;
       $I = (array) $IN; 
       $keys = array_keys($I);
       $desc ? rsort($keys) : asort($keys);
       foreach ($keys as $k) {
           $v = $I[$k]; 
           //$v = json_decode($I[$k],1) ?: $I[$k]; // force conversion of json_string
           if (is_array($v) || is_object($v)) {
               $O->$k = self::deep_order($v, $desc);
           }
           else {
               $O->$k=$v;
           }
       }
    return $O; // object
    } 

}

use like

$ordered_obj = \\a_nsp\\object_utils::deep_order($orig_obj)

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