代码之家  ›  专栏  ›  技术社区  ›  Rhys

如何使用自定义标记打印多维数组中的所有项?

  •  2
  • Rhys  · 技术社区  · 15 年前

    我有一个类似的多维数组:

    (
      [0] (
        title: 'First Group'
        type: 'group'
        children: (
          [0] (
            title: 'Inner Group'
            type: 'group'
            children: (
              [0] (
                title: 'Deep image'
                type: 'image'
              )
              [1] (
                title: 'Another deep image'
                type: 'image'
              )
            )
          )
        )
      )
      [1] (
        title: 'Root depth image'
        type: 'image'
      )
    )
    

    我希望能够通过这个数组和它的所有子数组(这个数组可以无限递归)将内容打印/回显到浏览器中。

    我遇到的问题是能够为不同类型的项指定特定的标记(甚至对每个项执行条件语句)。

    仅当每个图像与正则表达式匹配时才打印出其标题等。

    我能理解的唯一递归排序数组的方法必须是一个在找到子数组时调用自身的方法/函数,但如果是这样的话,我似乎无法执行条件语句。

    如果存在循环过程(不使用函数),这可能是最合适的选项,因此在每个子对象上,每个项目可以执行任何所需的条件。 我试过了 虽然 foreach公司 循环但没有用。

    注: 我已经从两个非递归的源数组编译了这个数组,如果这有助于解决方案的话,我可以使用这些具有相关键的数组。

    2 回复  |  直到 15 年前
        1
  •  1
  •   kalyan    15 年前

    如果函数变得过于复杂,则需要一个处理程序与递归函数一起执行该任务。

    function walk($array, $handler)
    {
      foreach($array as $obj) {
          if(is_array($obj['children'])) {
            walk($obj['children'], $handler); //RECURSION
          } else {
            $handler($obj);
          }
       }
    }
    

    然后为“image”类型的每个数组元素编写handler函数、regexp或它应该执行的任何作业

    function array_handler ($single_array){
             #Do some regexp or more complex job here.
         print $single_array['url']."<br/>";
    }
    

    当你必须打电话的时候,

    walk ($myarray, 'array_handler');
    

    基本上,我们定义了一个名为walk的新方法,它的行为类似于for each和while,但是代码块将由每个元素的处理程序执行。

    完整的代码,

    <?php
    $myarray = array( array (
               "title" => 'First Group',
               "type" => 'group',
               "children" => array (
                       array ("title" => 'Inner Group',
                            "type" => "group",
                        "children" => array (
                                       array (
                               "title" => "Deep Image",
                                       "type" => 'image',
                               "url" => "image.jpg"
                                   ),
                                   array (
                                       "title" => 'Another Deep Image',
                                   "type" => 'image',
                               "url" => "image2.jpg"    
                                   )
                        )      
                    )
    
                   )
                ),
                     array (
                  "title" => 'Root Deep Image',
                  "type" => 'image',
                          "url" => "image.jpg"
             )
            );
    
    
    
    
    function walk($array, $handler)
    {
      foreach($array as $obj) {
          if(is_array($obj['children'])) {
              walk($obj['children'], $handler); //RECURSION
          } else {
        $handler($obj);
          }
       }
    
    }
    
    function array_handler ($single_array){
         print $single_array['url']."<br/>";
    }
    
    walk ($myarray, 'array_handler');
    
    ?>
    
        2
  •  1
  •   Jacob Relkin    15 年前

    由于未定义输入大小,因此只能递归地解决此问题。

    也就是说,你可以试试这样的东西:

     $regexp_map = array(
         'group' => 'some regexp',
         'image' => 'some other regexp'
     );
    
    function walk($array) {
       $output = '';
       foreach($array as $obj) {
          if(is_array($obj['children'])) {
              $output .= walk($value['children']); //RECURSION
          } else {
              $regexp = $regexp_map[$obj['type']];
              if(preg_match($regexp, $obj['title'])) 
                 $output .= $obj['title'];
          }
       }
       return $output;
    }