2013-07-11 152 views
0

我有這樣一個數組:重組陣列樹形結構在PHP

$array = array(
    array('id' => 'foo.bar'), 
    array('id' => 'foo'), 
    array('id' => 'foo.baz.bar'), 
    array('id' => 'foo.bar.bar'), 
); 

我可以splitid領域,讓他們爲路徑,然後我想將它們整理成一棵樹。 ..我想這:

$result = array(); 

foreach($array as $element) { 
    $path = explode('.', $element['id']); 

    $subtree = $result; 
    while(!empty($path)) { 
     $path_element = array_shift($path); 

     if(empty($path_element)) { 
      $subtree['data'] = $element; 
     } else { 
      if(!is_array($subtree[$path_element])) { 
       $subtree[$path_element] = array(); 
      } 
      $subtree = $subtree[$path_element]; 
     } 
    } 
} 

但我得到的是警告的負載和空$res - 陣列。

PHP Notice: Undefined index: foo in tree.php on line 24 
PHP Stack trace: 
PHP 1. {main}() tree.php:0 
PHP Notice: Undefined index: bar in tree.php on line 24 
PHP Stack trace: 
PHP 1. {main}() tree.php:0 
PHP Notice: Undefined index: foo in tree.php on line 24 
PHP Stack trace: 
PHP 1. {main}() tree.php:0 
PHP Notice: Undefined index: foo in tree.php on line 24 
PHP Stack trace: 
PHP 1. {main}() tree.php:0 
PHP Notice: Undefined index: baz in tree.php on line 24 
PHP Stack trace: 
PHP 1. {main}() tree.php:0 
PHP Notice: Undefined index: bar in tree.php on line 24 
PHP Stack trace: 
PHP 1. {main}() tree.php:0 
PHP Notice: Undefined index: foo in tree.php on line 24 
PHP Stack trace: 
PHP 1. {main}() tree.php:0 
PHP Notice: Undefined index: bar in tree.php on line 24 
PHP Stack trace: 
PHP 1. {main}() tree.php:0 
PHP Notice: Undefined index: bar in tree.php on line 24 
PHP Stack trace: 
PHP 1. {main}() tree.php:0 

(第24行是$s = $s[$pe];

任何暗示?

EDIT:我的期望的輸出會是這樣

$res = array(
    'foo' => array(
    'data' => ... 
    'bar' => array(
     'data' => ... 
     'bar' => array(
     'data' => ... 
    ), 
    ), 
    'baz' => array(
     'bar' => array(
     'data' => ... 
    ), 
    ), 
), 
); 

data元素是從陣列的原始元素。

+1

你有一個例子樹如何看起來像? – Benz

+1

你沒有把任何東西放在$ res中,難怪它是空的。另外,我甚至不知道它應該做什麼。 – enrey

+0

@Benz增加了一個例子。 – Lanbo

回答

1

下面的代碼會生成以下結果:

Array 
(
    [foo] => Array 
    (
     [data] => ... 
     [baz] => Array 
      (
       [bar] => Array 
        (
         [data] => ... 
        ) 

     ) 

     [bar] => Array 
     (
      [bar] => Array 
      (
       [data] => ... 
      ) 
     ) 
    ) 
) 

我改名一些你變量...

$array = array(
    array('id' => 'foo.bar'), 
    array('id' => 'foo'), 
    array('id' => 'foo.baz.bar'), 
    array('id' => 'foo.bar.bar'), 
); 


$res = array(); 

foreach($array as $e) { 

    $parts = explode('.', $e['id']); 

    $temp = &$res; 

    foreach($parts as $key => $el) { 
     if (!isset($temp[$el])) $temp[$el] = array(); 

     if ($key == count($parts)-1) $temp[$el] = array('data' => '...'); 
     $temp = &$temp[$el]; 
    } 
} 

print_r($res); 
0

使用&使$ s引用$ res。這將通過引用而不是按值傳遞數據。

$a = array(
    array('id' => 'foo.bar'), 
    array('id' => 'foo'), 
    array('id' => 'foo.baz.bar'), 
    array('id' => 'foo.bar.bar'), 
); 

$res = array(); 

foreach($a as $e) { 
    $p = explode('.', $e['id']); 

    $s = &$res; 
    while(!empty($p)) { 
     $pe = array_shift($p); 
     if(empty($p)) { 
      $s['data'] = $e; 
     } else { 

      if(!isset($s[$pe])) { 
       $s[$pe] = array(); 
      } 
      $s = &$s[$pe]; 
     } 
    } 
} 

echo '<pre>'; 
print_r($res); 
echo '</pre>'; 

結果

Array 
(
    [foo] => Array 
     (
      [data] => Array 
       (
        [id] => foo.bar 
       ) 

      [baz] => Array 
       (
        [data] => Array 
         (
          [id] => foo.baz.bar 
         ) 

       ) 

      [bar] => Array 
       (
        [data] => Array 
         (
          [id] => foo.bar.bar 
         ) 

       ) 

     ) 

    [data] => Array 
     (
      [id] => foo 
     ) 

) 
0

遞歸是你的答案。

,你需要沿着線的東西:

<?php 

$a = array(
    array('id' => 'foo.bar'), 
    array('id' => 'foo'), 
    array('id' => 'foo.baz.bar'), 
    array('id' => 'foo.bar.bar'), 
); 

function createTree($path) { 
    if (count($path) === 1) { 
     return array($path[0]=>array('data'=>'some random data here')); 
    } else { 
     $currentRoot = array_shift($path); 
     return array($currentRoot => createTree($path)); 
    } 
} 

$result = array(); 

foreach ($a as $item) { 
    $result = array_merge_recursive(
     $result, 
     createTree(
      explode('.',$item['id']) 
     ) 
    ); 
} 

// $result now is what you wanted