2012-01-16 46 views
2

我很驚訝沒有在SO上找到答案(或者在互聯網上的其他地方)。它涉及到一個嵌套的縮進列表,我想根據縮進級別將其轉換爲多維數組。向多維數組縮進的列表

通過舉例的方式,下面是一些示例輸入:

Home 
Products 
    Product 1 
     Product 1 Images 
    Product 2 
     Product 2 Images 
    Where to Buy 
About Us 
    Meet the Team 
    Careers 
Contact Us 

理想情況下,我想這送入一些(遞歸?)功能,得到下面的輸出:

array(
    'Home' => array(), 
    'Products' => array(
     'Product 1' => array(
      'Product 1 Images' => array(), 
     ), 
     'Product 2' => array(
      'Product 2 Images' => array(), 
     ), 
     'Where to Buy' => array(), 
    ), 
    'About Us' => array(
     'Meet the Team' => array(), 
     'Careers' => array(), 
    ), 
    'Contact Us' => array(), 
); 

我很困惑執行這樣的任務所需的邏輯,所以任何幫助將不勝感激。

+5

列表如何縮進,標籤||空間|| html ... – 2012-01-16 14:03:19

+0

似乎可以將縮進方法(例如以字符串形式)傳遞給構建此數組數組的函數。 – Crontab 2012-01-16 14:07:28

回答

9

因爲目前還不清楚您是否'試圖從給定的結構(html-dom)或者從給定的字符串讀取純文本,我認爲它是你想要解析的字符串。如果是這樣,請嘗試:

<?php 
$list = 
'Home 
Products 
    Product 1 
     Product 1 Images 
    Product 2 
     Product 2 Images 
    Where to Buy 
About Us 
    Meet the Team 
    Careers 
Contact Us'; 

function helper($list, $indentation = ' ') { 
    $result = array(); 
    $path = array(); 

    foreach (explode("\n", $list) as $line) { 
    // get depth and label 
    $depth = 0; 
    while (substr($line, 0, strlen($indentation)) === $indentation) { 
     $depth += 1; 
     $line = substr($line, strlen($indentation)); 
    } 

    // truncate path if needed 
    while ($depth < sizeof($path)) { 
     array_pop($path); 
    } 

    // keep label (at depth) 
    $path[$depth] = $line; 

    // traverse path and add label to result 
    $parent =& $result; 
    foreach ($path as $depth => $key) { 
     if (!isset($parent[$key])) { 
     $parent[$line] = array(); 
     break; 
     } 

     $parent =& $parent[$key]; 
    } 
    } 

    // return 
    return $result; 
} 

print_r(helper($list)); 

演示:http://codepad.org/zgfHvkBV

+0

謝謝你,Yoshi。完美的作品:-) – 2012-01-17 11:09:29

-2

有一個關於PHP腳本的課程,可以滿足您的需求。你可以在這裏找到它: Array To List

它需要一個多維數組並創建HTML。

更新

實際上所需的與此相反。爲此,最好使用DOMDocument對象並將HTML加載到對象表示中。

http://php.net/manual/en/domdocument.loadhtml.php

+0

謝謝,但我在一個腳本後,可以做你所描述的相反。 – 2012-01-16 14:10:34

+0

噢,你可能想在這種情況下將它解析成DOMDocument。看看loadHTML:http://php.net/manual/en/domdocument.loadhtml.php – 2012-01-16 14:12:21

0

我不會寫遞歸函數,但要指出你在一個有益的方向,看看PHP的substr_count功能。基於此,您可以計算每行前面的選項卡數量,並將其與前一行中的選項卡數量進行比較,以確定它是否爲兒童,兄弟姐妹等。

0

我是唯一一個用美麗的心靈看到的格局?

輸入數組幾乎是一樣的東西,只有3種可能的方式結束:打開,全部或關閉括號。

$L = 4;//estimate depth level 

function tabbed_text_to_array ($raw, $L) { 

     $raw = preg_replace("/^(\\t*)([^\\t\\n]*)\\n?/m" , "\t$1'$2' => array(\n" , $raw); 

    for(; $L > 0 ; $L--) { 

     for($i=0; $i<3 ;$i++) { 
      $preL = $L-1; 
      $s = array("^(\\t{{$L}})([^\\t\\),]*)(?=\\n\\t{{$L}}')", "^(\\t{{$L}})([^\\t\\),]*)(?=\\n(\\t{0,{$preL}})')", "^(\\t{{$L}})(\\),)(?=\\n(\\t{{$preL}})[^\t])"); 
      $r = array( "$1$2)," ,  "$1$2)\n" . str_repeat("\t",$preL) . ")," , "$1),\n$3)," ); 
      $raw = preg_replace("/$s[$i]/m" , $r[$i], $raw); 
     } 
    } 
    return "array(\n". $raw. ")\n);"; 

} 

該函數生成一個帶有文字數組的字符串。然後你只需eval()它。 它看起來不像它糟糕。雙反斜線使閱讀更難,但很簡單。

與細胞複製一樣,它首先在一次傳遞中添加最常見的東西:引號,逗號和開括號,然後在兩次傳遞中添加較小的細節。這些都爲每個級別運行,一旦你指定(你可以浪費在尋找出來的最深層次,從開始加工代碼,但猜測是不夠的。)

看到了工作演示/ tool to convert tab-indented text into array

或訪問php fiddle所有的通行證,所以你可以擴大這一點。