2016-09-24 25 views
0

私は次の配列を持っています。配列にはn個の子があるので、配列の深さはわかりません。入れ子配列のPHP再帰的反復

$menu = [ 
    [ 
     'name' => 'home', 
     'label' => 'Home', 
     'uri' => '/home', 
     'order' => 1, 
     'attributes' => [ 
      'class' => ['home-class', 'home-class-2'], 
      'id' => ['home-id'] 
     ] 
    ], [ 
     'name' => 'about', 
     'label' => 'About', 
     'uri' => '/about', 
     'order' => 2, 
     'attributes' => [ 
      'class' => [], 
      'id' => [] 
     ], 
     'child' => [ 
      [ 
       'name' => 'company_profile', 
       'label' => 'Company Profile', 
       'uri' => '/company-profile', 
       'order' => 1, 
       'attributes' => [ 
        'class' => [], 
        'id' => [] 
       ] 
      ], [ 
       'name' => 'team', 
       'label' => 'Team', 
       'uri' => '/team', 
       'order' => 2, 
       'attributes' => [ 
        'class' => ['team-class', 'team-class-2'], 
        'id' => ['team-id'] 
       ], 
       'child' => [ 
        [ 
         'name' => 'management_team', 
         'label' => 'Management Team', 
         'uri' => '/management-team', 
         'order' => 1, 
         'attributes' => [ 
          'class' => [], 
          'id' => [] 
         ] 
        ], 
        [ 
         'name' => 'development_team', 
         'label' => 'Development Team', 
         'uri' => '/development-team', 
         'order' => 2, 
         'attributes' => [ 
          'class' => [], 
          'id' => [] 
         ] 
        ], 

       ] 
      ], 
     ] 
    ], [ 
     'name' => 'services', 
     'label' => 'Services', 
     'uri' => '/services', 
     'order' => 3, 
     'attributes' => [ 
      'class' => [], 
      'id' => [] 
     ], 
     'child' => [ 
      [ 
       'name' => 'web_application', 
       'label' => 'Web Application', 
       'uri' => '/web-application', 
       'order' => 1, 
       'attributes' => [ 
        'class' => [], 
        'id' => [] 
       ] 
      ], [ 
       'name' => 'mobile_application', 
       'label' => 'Mobile Application', 
       'uri' => '/mobile-application', 
       'order' => 2, 
       'attributes' => [ 
        'class' => [], 
        'id' => [] 
       ] 
      ], [ 
       'name' => 'cms_development', 
       'label' => 'CMS Development', 
       'uri' => '/cms-development', 
       'order' => 3, 
       'attributes' => [ 
        'class' => [], 
        'id' => [] 
       ] 
      ], 
     ] 
    ] 
]; 

たとえば、これをループしてデータをオブジェクトに渡したいとします。

$nav = new Navigation\Menu('main'); 
foreach ($menu as $item) { 
    // Parent element 
    $navItem = new Navigation\Item($item['name']); 
    $navItem->setLabel($item['label']); 
    $navItem->setUri($item['uri']); 
    $nav->addItem($navItem); 
    if (isset($item['child']) && is_array($item['child'])) { 
     // First child 
     foreach ($item['child'] as $child1) { 
      $childItem1 = new Navigation\Item($child1['name']); 
      $childItem1->setLabel($child1['label']); 
      $childItem1->setUri($child1['uri']); 
      $navItem->addChild($childItem1); 
      if (isset($child1['child']) && is_array($child1['child'])) { 
       // Second child 
       foreach ($child1['child'] as $child2) { 
        $childItem2 = new Navigation\Item($child2['name']); 
        $childItem2->setLabel($child2['label']); 
        $childItem2->setUri($child2['uri']); 
        $childItem1->addChild($childItem2); 
       } 
      } 
     } 
    } 
} 

これは問題はありますが、問題はあります。あなたが見ているように、私は手作業で各子をループしています。私はこれを望んでいません。何を探していますか?再帰的に配列を反復して、任意の深さの子を追加できます。

array_walk_recursiveまたはカスタムの再帰関数を何も実行せずに試しました。これを解決するための任意のポインタが評価されます。

ありがとうございました。

+1

'RecursiveArrayIterator'は良い選択かもしれない – RamRaider

+0

私が試した、要素を追加するとき、その子と深さを維持している使用に問題があることを思われます。 –

答えて

1

最後に考え出しました。

ここでは、カスタム再帰関数を使用しています。

function recursive($menu, &$nav, $child = false, $parent = null) 
{ 
    foreach ($menu as $page) { 
     $navItem = new Navigation\Item($page['name']); 
     if (false == $child) { 
      $nav->addItem($navItem); 
     } else { 
      $parent->addChild($navItem); 
     } 
     if (isset($page['child'])) { 
      recursive($page['child'], $nav, true, $navItem); 
     } 
    } 
} 

$nav = new Navigation\Menu('main'); 
recursive($menu, $nav); 
1

ここでは、配列またはオブジェクトの場合はすべてを実行する必要のある小さな再帰的なスクリプトですが、各再帰によってオブジェクトが返されます。これで、あなたの使用のためにいくつかの編集が必要になります。しかしそれはあなたに出発点を与えるはずです。

function Navigation($item) { 
    if (is_object($item)) { 
     foreach (get_object_vars($item) as $property => $value) { 
      //If item is an object, then run recursively 
      if (is_array($value) || is_object($value)) { 
       $item->$property = Navigation($item); 
      } else { 
       $navItem->setLabel($item['label']); 
       $navItem->setUri($item['uri']); 
       $nav->addItem($navItem); 
      } 
     } 
     return $nav; 
    } elseif (is_array($item)) { 
     foreach ($item as $property => $value) { 
      //If item is an array, then run recursively 
      if (is_array($value) || is_object($value)) { 
       $item[$property] = Navigation($item); 
      } else { 
       $navItem->setLabel($item['label']); 
       $navItem->setUri($item['uri']); 
       $nav->addItem($navItem); 
      } 
     } 
     return $nav; 
    } 
    $navItem->setLabel($item['label']); 
    $navItem->setUri($item['uri']); 
    $nav->addItem($navItem); 
} 
+0

Andrewさん、ありがとうございました。これは、+1の投票に役立ちました。正解を投稿します。 –

+1

私は助けてくれるとうれしいです。時にはカスタムの反復スクリプトが最も簡単な方法です。 – AndrewL

関連する問題