doujin4031 2012-12-14 21:32
浏览 139
已采纳

使用PHP的RecursiveIteratorIterator迭代多维数组

I have to cache a tree structure and access it later on. Problem: I really can't figure out how to declare the data so that it fits to RecursiveIteratorIterator etc. It's probably a very n00bish question, but I have tried lots of combinations and ran out of ideas :-(

Conceptually the data looks like this:

ROOT code : 1111, label : Universe
   - code : 2000, label : Asia
      - code : 3203, label : Hongkong
           -code : 2081, label: Greater Area
           -code : 2041, label: Downtown
      - code : 4020, label : Shanghai
   - code : 6201, label : Africa
   - code : 321, label : North America

I want to access all direct childs to a given code, e.g. for Asia Hongkong and Shanghai. RecursiveIteratorIterator seems to make this easy.

// looking for Asia with code = 2000
$iterator = new RecursiveIteratorIterator(new Universe_Tree($tree));
foreach ($iterator as $key => $item) {
       if ($item->code == 2000) {
            var_dump($iterator->callGetChildren());

       }
}

Class Universe_Tree does not do much yet:

class Universe_Tree extends ArrayIterator implements RecursiveIterator  {

    public function hasChildren() {
        return (is_array($this->current()));
    }

    public function getChildren() {
        return new self($this->current());
    }

}

My best approach was to create objects of each node and store them in a nested array

$universe = new stdClass();
$universe ->code = 1111;
$universe ->label = "Universe"; 

$tree = array(
  array($universe,
    array(
       $asia,
      (array($shanghai,$hongkong)),
       $europe
        // and so on
       )
      );

Unfortunately $iterator->callGetChildren() does not return the children, just the current element. Probably because the nodes are not nested together correctly. I also tried to nest arrays with a parentId but this lead to an error message from ArrayIterator that this is not an array or object, though according to var_dump it was an array. What else could I try?

  • 写回答

1条回答 默认 最新

  • duanbipu7601 2012-12-16 17:03
    关注

    This is a kind of answer. Actually I gave up and went to a solution based on SimpleXML. Really simple and very few code. Eventually somebody will come across this question and my "solution" might be a way for him, too. So I'll include it here:

    // data represented as xml
    $xmlstring = <<<XML
    <orgtree>
      <level number="1">
            <unit label="Universe" code="1111">
                <level number="2">
                    <unit label="Asia" code="2000"></unit>
                        <level number="3">
                            <unit label="Hongkong" code="3203"></unit>
                               <level number="4">
                                   <unit label="Greater Area" code="2081"></unit>
                                   <unit label="Downtown" code="2041"></unit>
                               </level>
                        </level>
                    </unit>
                <unit label="Africa" code="6201"></unit>
                <unit label="North America" code="321"></unit>
                </level>
            </unit>
        </level>
    </orgtree>
    XML;
    
    
       $xml = simplexml_load_string($xmlstring);
       // use xpath to select part of xml
       foreach ($xml->xpath('//unit[@code="2000"]') as $parentUnit)
       {
            $subtree = $parentUnit->level;
            foreach ($subtree->unit as $unit) {
                     var_dump($unit["label"]);
            }
       }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器