对象的递归遍历

4

我在编写递归函数以遍历这个层次结构时遇到了困难

    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....>

正如您所看到的,这个嵌套集可以无限扩展。

我想要返回的是这样的内容。

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

[编辑]:我正在使用递归函数来“展平”数组或对象。我认为我可以修改这个函数来获得我想要的数据结构,但是还没有完全搞清楚。

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

我的问题是我无法弄清如何递归地构建我所需的结构,或者也许有一种更加优雅的PHP方法可以做到这一点?


你考虑过使用 JSON 吗? - Lim H.
嗯...我还没有,最终可能需要将它传递给JavaScript,所以这可能是一个开始。 - bonez
如果您使用JSON,您也可以直接在对象上使用json_encode。 - Jack
关于您关于将值转换为数组的问题,我不明白为什么您要这样做。为什么 is_array() 在这里不起作用? - Lim H.
1
你创建了一个类对象吗?你能给这个类添加一个方法吗?比如 getChildren(),你可以递归调用它。 - Bjørne Malmanger
显示剩余3条评论
3个回答

5

试试这个

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

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

修改为: function getCategoryTree($tree) { $return = array(); foreach ($tree->children as $child) { if(count($child->children) > 0) { $return[$child->name] = $this->getCategoryTree($child); } else { $return[] = $child->name; } } return empty($return) ? NULL : (count($return) == 1 ? reset($return) : $return); } --修改后最后一个子元素不再是数组,而是字符串。 - bonez
对不起,那个方法行不通...我该怎么做才能使最后一个条目不是空数组? - bonez

1

我没有时间写一个可行的答案,但是这里有一些伪代码可以实现它(一半是PHP,一半是JS)

这将通过删除列表中每个元素的子属性来创建树的扁平化版本。

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

0

deep_order 对象或 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
    } 

}

使用方法如下:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接