2017-02-14 134 views
1

多維數組我想從下面生成一個PHP多維數組 -生成列表字符串

- Item 1 
-- Item 1.1 
-- Item 1.2 
--- Item 1.2.1 
--- Item 1.2.2 
---- Item 1.2.2.1 
- Item 2 
- Item 3 
- Item 4 
-- Item 4.1 
-- Item 4.2 

我的最終目標是這個字符串轉換成無序列表。

我想象最好的方法來做到這一點將創建一個遞歸函數。在一個美好的一天,我確信我可以解決這個問題,但我有點空虛!

陣列結構應該像下面轉儲 -

array(6) { 
    [0]=> 
    string(6) "Item 1" 
    [1]=> 
    array(3) { 
    [0]=> 
    string(8) "Item 1.1" 
    [1]=> 
    string(8) "Item 1.2" 
    [2]=> 
    array(3) { 
     [0]=> 
     string(10) "Item 1.2.1" 
     [1]=> 
     string(10) "Item 1.2.2" 
     [2]=> 
     array(1) { 
     [0]=> 
     string(12) "Item 1.2.2.1" 
     } 
    } 
    } 
    [2]=> 
    string(6) "Item 2" 
    [3]=> 
    string(6) "Item 3" 
    [4]=> 
    string(6) "Item 4" 
    [5]=> 
    array(2) { 
    [0]=> 
    string(8) "Item 4.1" 
    [1]=> 
    string(8) "Item 4.2" 
    } 
} 

希望能對你有所幫助。

+0

https://www.google.com/search?q=build+multidimensional+array+from+string+recursion //大部分結果似乎是針對PHP的,但由於您甚至沒有提及或標記具體的語言,那我必須這樣做。 – CBroe

+0

@CBroe感謝您的Google鏈接。這是PHP - 對不起,我忘了包括現在添加它。這比你的標準字符串遞歸複雜一點 – Chris

+0

從上面的註釋中,你可以給出一個提示數組應該是什麼樣子? –

回答

2

下面將轉換直接進入HTML,而不遞歸:

$text = array(); 
$text[] = '- Item 1'; 
$text[] = '-- Item 1.1'; 
$text[] = '-- Item 1.2'; 
$text[] = '--- Item 1.2.1'; 
$text[] = '--- Item 1.2.2'; 
$text[] = '---- Item 1.2.2.1'; 
$text[] = '- Item 2'; 
$text[] = '- Item 3'; 
$text[] = '- Item 4'; 
$text[] = '-- Item 4.1'; 
$text[] = '-- Item 4.2'; 

$previous_dash_count = 0; // topmost parent 
foreach ($text as $line) { 
    if (preg_match('/(^\-+)(.*)/', $line, $matches, PREG_OFFSET_CAPTURE)===1) { 
     $dash_count = strlen($matches[1][0]); 
     $title = $matches[2][0]; 

     if ($dash_count == $previous_dash_count) { 
      echo "<li>$title</li>\n"; 
     } elseif ($dash_count > $previous_dash_count) { 
      echo str_repeat("<ul>\n", $dash_count - $previous_dash_count); 
      echo "<li>$title</li>\n"; 
     } else { 
      echo str_repeat("</ul>\n",$previous_dash_count-$dash_count+1); 
      echo "<ul>\n"; 
      echo "<li>$title</li>\n"; 
     } 

     $previous_dash_count = $dash_count; 
    } 
} 
echo str_repeat("</ul>\n",$previous_dash_count); 

我做幾個假設。輸入文本總是表現良好並且不包含隨機性。另外我不會假設UTF-8文本,但是您可以安全地使用破折號。

這裏是在其所有的榮耀血腥數組版本:

$stack = array(); 
$previous_dash_count = 0; 
$parent_node = array(); 
foreach ($text as $line) { 
    if (preg_match('/(^\-+)(.*)/', $line, $matches, PREG_OFFSET_CAPTURE)===1) { 
     $dash_count = strlen($matches[1][0]); 
     $title = $matches[2][0]; 

     if ($dash_count == $previous_dash_count) { 
      $parent_node[] = $title; 
     } elseif ($dash_count > $previous_dash_count) { 
      for ($push_count = $previous_dash_count; $push_count<$dash_count; $push_count++) { 
       array_push($stack, $parent_node); // remember node 
       $new_child = array(); 
       $new_child[] = $title; 
       $parent_node[] = $new_child; 
       $parent_node = $new_child; 
      } 
     } else { 
      for ($pop_count = $previous_dash_count; $pop_count >$dash_count; $pop_count--) { 
       $old_child = $parent_node; 
       $parent_node = array_pop($stack); 
       $parent_node[] = $old_child; 
      } 
      $parent_node[] = $title; 
     } 

     $previous_dash_count = $dash_count; 
    } 
} 
for ($pop_count = $previous_dash_count; $pop_count > 0; $pop_count--) { 
    $old_child = $parent_node; 
    $parent_node = array_pop($stack); 
    $parent_node[] = $old_child; 
} 

print_r($parent_node); 

我們保持陣列節點的堆棧,所以我們有一個孩子與其父之間的聯繫。請注意,此代碼的結構與直接HTML版本的結構相同。

+0

謝謝 - 我最終不得不採用這種方法,因爲它是最簡單的。稍微不同的技巧,但你的答案是正確的。乾杯! – Chris

+0

太棒了,非常感謝你! Cudos :) – Chris

+0

很高興爲您提供幫助。這比我想象的要難,它讓我流汗... –