2010-11-26 22 views
2

J'ai un tableau multidimensionnel semblable à ceci:Comment imprimer tous les éléments d'un tableau multidimensionnel avec un balisage personnalisé?

(
    [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' 
) 
) 

Je veux être en mesure de me frayer un chemin à travers ce tableau et tous ses enfants (ce tableau pourrait être infiniment récursive) pour imprimer/écho du contenu sur le navigateur. Le problème que j'ai est de pouvoir spécifier un certain balisage (et même effectuer des conditions sur chaque élément) pour les différents types d'éléments.

Par exemple. Imprimer le titre de chaque image seulement si elle correspond à une expression régulière, etc.

La seule méthode que je peux comprendre qui triera récursivement un tableau doit être une méthode/fonction qui s'appelle chaque fois que des enfants sont trouvés, mais il semble que je ne serai pas en mesure d'effectuer les conditions si c'est le cas.

Si un processus de boucle (n'utilisant pas de fonction) existe, ce serait probablement l'option la plus appropriée, donc pour chaque enfant, je peux effectuer toutes les conditions requises par élément. J'ai essayé avec tandis que et foreach boucles mais en vain.

NB: J'ai compilé ce tableau à partir de deux tableaux source qui n'étaient pas récursifs, et pourrait utiliser ces tableaux qui ont des clés connexes, si cela aide la solution.

Répondre

1

Si la fonction d'obtenir plus complexe que vous avez besoin d'un gestionnaire pour faire le travail ainsi que la fonction récursive.

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

puis rédigez votre fonction de gestionnaire, regexp ou tout autre travail son supposé pour chaque élément de tableau de type 'image'

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

et quand vous devez appeler,

walk ($myarray, 'array_handler'); 

fondamentalement, nous avons défini une nouvelle méthode appelée walk qui agit comme foreach et while, mais le codeblock sera exécuté par le gestionnaire pour chaque élément.

Code complet,

<?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'); 

?> 
+0

et avoir la méthode de marche comme module commun disponible dans votre code et l'utiliser partout comme vous utilisez foreach/alors – kalyan

+0

Merci ce concept est exactement ce que je suis après. J'ai effectivement étendu cela pour permettre des chaînes avec des espaces réservés, ou des fonctions personnalisées, en fonction de ce qui est requis sur une base par article – Rhys

1

Vous ne pouvez résoudre ce problème que récursivement, car la taille d'entrée n'est pas définie.

Cela dit, vous pouvez essayer quelque chose comme ceci:

$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; 
} 
+0

Merci pour les conseils. Bien que les expressions régulières ne soient qu'un exemple de la façon dont je veux manipuler les données, malheureusement, je pourrais voir cette fonction devenir trop complexe pour permettre les différentes possibilités de manipulation dont j'ai besoin. – Rhys