2009-07-09 73 views
1

我有此數組:轉換的一維數組,多維數組在PHP

Array 
(
    [1] => animal 
    [1-1] => turtle 
    [1-1-1] => sea turtle 
    [1-1-2] => box turtle 
    [1-1-3] => green turtle 
    [1-1-3-1] => green turtle with brown tail 
) 

,我想一些如何將其轉換成:

Array 
(
    [1-title] => animal 
    [1-sons] => array(
      [1-1-title] => turtle 
      [1-1-sons] => array(
        [1-1-1] => sea turtle 
         [1-1-2] => box turtle 
        [1-1-3-title] => green turtle 
        [1-1-3-sons] => array(
          [1-1-3-title] => green turtle 
           ) 
        ) 
      ) 
) 

或者你可以建議更好的方法組織輸出數組..

但如何做到這一點?

我知道這不是一件容易的事,在所有的,我正在寫一個解析器會走的數據,使樹了出來..

預先感謝您的幫助和建議..

+0

您正在使用類型數組來處理表格/分層數據。我有預感會有更多(龜,犰狳,iquana),並且遞歸可能會繼續(與雀斑,尾巴真菌)。但是你沒有提到數據庫存儲。我想知道你是否考慮過使用XML?你是否在PHP之外處理過分層數據? (你說你知道這不容易,但是你真的知道它「不容易」嗎?!) – Smandoli 2009-07-09 16:28:20

+0

好吧,我的例子的解決方案將被添加到一個更大的類,這是一種文本解析器,我需要從文本中編寫這個樹,在這裏和那裏寫一個大的文本字段(數據庫),用戶不必編寫那些1-1-2的東西,但它是從另一個讀取文本並理解它的函數生成的,然後給這個數組。所以這是不可能考慮xml在這裏我認爲.. – 2009-07-09 17:05:19

回答

8

組織數據會以這樣的方式的最簡單的方法:

array (
    'Animal' => 
    array (
    'Turtle' => 
    array (
     'Sea Turtle', 
     'Box Turtle', 
     'Green Turtle' => 
     array (
     'Green Turtle With Brown Tail', 
    ), 
     'Common Turtle', 
    ), 
), 
); 

// Or, otherwise written (equivalent to the above) 

$animals = array(); 
$animals['Animal'] = array(); 
$animals['Animal']['Turtle'] = array(); 
$animals['Animal']['Turtle'][] = 'Sea Turtle'; 
$animals['Animal']['Turtle'][] = 'Box Turtle'; 
$animals['Animal']['Turtle']['Green Turtle'] = array(); 
$animals['Animal']['Turtle']['Green Turtle'][] = 'Green Turtle With Brown Tail'; 
$animals['Animal']['Turtle'][] = 'Common Turtle'; 

從本質上講,動物的名字是價值,除非它有孩子,那麼這個值是一個數組,關鍵是動物的名字。


這樣的話,你可以很容易地通過執行以下操作解析值:

parse_animals($animals); 

function parse_animals($array, $indent = 0) { 
    if(!is_array($array)) return; // A little safe guard in case. 

    foreach($array as $key => $value) { 
    echo str_repeat(' ', $indent) . "- "; 

    if(is_array($value)) { 
     echo $key . "\n"; 
     parse_animals($value, $indent + 1); 
    } else { 
     echo $value . "\n"; 
    } 
    } 
} 

在控制檯上面會輸出如下:

- Animal 
    - Turtle 
    - Sea Turtle 
    - Box Turtle 
    - Green Turtle 
     - Green Turtle With Brown Tail 
    - Common Turtle 

編輯:和這裏是一個版本,將輸出它的網頁。

function parse_animals_web($array) { 
    if(!is_array($array)) return; // A little safe guard in case. 

    foreach($array as $key => $value) { 
    echo '<ul>'; 

    if(is_array($value)) { 
     echo '<li>' . htmlentities($key) . "</li>"; 
     parse_animals_web($value); 
    } else { 
     echo '<li>' . htmlentities($value) . "</li>"; 
    } 

    echo '</ul>'; 
    } 
} 

的輸出是:

  • 動物
    • 龜背
    • 海龜
    • 箱龜
    • 綠龜
      • 綠龜尾布朗
    • 常見的龜

也許你要得到一個動物的孩子。

function get_children_of($array, $name) { 
    foreach($array as $key => $value) { 
    if(is_array($value)) { 
     if($key === $name) { 
     return $value; 
     } else { 
     return get_children_of($value, $name); 
     } 
    } 
    } 

    return array(); 
} 

現在我們可以得到Green Turtle的所有孩子並輸出它們。

$green_turtle = get_children_of($animals, 'Green Turtle'); 
parse_array($green_turtle); 

輸出是:

- Green Turtle With Brown Tail 

編輯:既然你說你是停留在那個奇怪的格式輸入數組是,這裏是將轉換您的陣列功能轉換爲上面指定的格式:

function convert_array($array) { 
    $new_array = array(); 

    $keys = array_keys($array); 
    foreach($keys as $key) { 
    $level = explode('-', $key); 
    $cur_level = &$new_array; 
    $cur_key = ''; 

    foreach($level as $o_key) { 
     $cur_key = ltrim($cur_key . '-' . $o_key, '-'); 
     $next_key = $cur_key . '-1'; 
     $value = $array[$cur_key]; 
     $has_child = array_key_exists($next_key, $array); 

     if($has_child) { 
     if(!array_key_exists($value, $cur_level)) { 
      $cur_level[$value] = array(); 
     } 
     $cur_level = &$cur_level[$value]; 
     } else { 
     $cur_level[] = $value; 
     } 
    } 
    } 

    return $new_array; 
} 
+0

是的,這將是組織我的數據的最佳方式,我發現get_children_of函數是非常有用的。但parse_animals只是不按照你說的方式顯示數據,或者它不適合我。我只能發送一個如下的數組: Array ( [1] =>動物 [1-1] =>烏龜 [1-1-1] =>海龜 [1-1-2] =>箱龜 [1-1-3] =>綠海龜 [1-1-3-1] =>綠海龜棕尾 ) 然後我在它的輸出方式自由,但輸入無法更改... – 2009-07-09 16:48:17

+1

我添加了一個函數來將數組轉換爲上面指定的格式。 – 2009-07-09 17:20:36

1

這真的取決於你將如何使用生成的樹。你能否寫下更多關於這方面的細節?

0

試試這個:

$array = array(
    '1' => 'animal', 
    '1-1' => 'turtle', 
    '1-1-1' => 'sea turtle', 
    '1-1-2' => 'box turtle', 
    '1-1-3' => 'green turtle', 
    '1-1-3-1' => 'green turtle with brown tail' 
); 
$tree = array(); 
foreach ($array as $path => $val) { 
    $segments = explode('-', $path); 
    $last = array_pop($segments); 
    $tmp = &$tree; 
    $path = ''; 
    foreach ($segments as $segment) { 
     $path .= $segment.'-'; 
     if (!isset($tmp[$path.'sons'])) { 
      $tmp[$path.'sons'] = array(); 
     } 
     $tmp = &$tmp[$path.'sons']; 
    } 
    $tmp[$path.$last.'-title'] = $val; 
} 
print_r($tree); 

但是你的數據結構沒有多大意義。

0
$result = array(); 
foreach ($array as $position => $text) { 
    $p = explode('-', $position); 
    putIntoTree($result, $p, $text); 
} 

function putIntoTree(&$tree, $posInfo, $item) { 
    $index = array_shift($posInfo) - 1; 

    if (!count($posInfo)) { 
     $tree[$index]['name'] = $item; 
    } else {   
     if (!isset($tree[$index]['children'])) { 
      $tree[$index]['children'] = array(); 
     } 
     putIntoTree($tree[$index]['children'], $posInfo, $item); 
    } 
}  

結果在這,這似乎是一個合理的方式來保存數據。

Array 
(
    [0] => Array 
     (
      [name] => animal 
      [children] => Array 
       (
        [0] => Array 
         (
          [name] => turtle 
          [children] => Array 
           (
            [0] => Array 
             (
              [name] => sea turtle 
             ) 

            [1] => Array 
             (
              [name] => box turtle 
             ) 

            [2] => Array 
             (
              [name] => green turtle 
              [children] => Array 
               (
                [0] => Array 
                 (
                  [name] => green turtle with brown tail 
                 ) 
               ) 
             ) 
           ) 
         ) 
       ) 
     ) 
) 
0

你所想達到某種的一組嵌套,因此實現它會保存父ID在孩子們的入門最簡單的方法:

// the tree 
0 => array(parent => NULL, name => turtle), 
1 => array(parent => 0, name => green turtle), 
2 => array(parent => 0, name => blue turtle), 
3 => array(parent => 1, name => green turtle with yellow nose) 

你可以走通過這個層次使用一個簡單的遞歸函數。

如果使用對象而不是關聯數組,則甚至會提高性能。