2012-06-06 34 views
1

所以我的例子輸入是如何通過遞歸將此數組轉換爲多維數組?

$example_1 = Array (
    0 => Array (
     'category'  => 'body', 
     'sub-category' => 'intro', 
     'id'   => 'header', 
     'copy'   => 'Hello', 
    ), 
    1 => Array (
     'category'  => 'body', 
     'sub-category' => 'intro', 
     'id'   => 'footer', 
     'copy'   => 'Bye', 
    ), 
); 

$example_2 = Array (
    0 => Array (
     'category'  => 'body', 
     'sub-category' => 'intro', 
     'sub-sub-category' => 'header', 
     'sub-sub-child-category' => 'left', 
     'id'   => 'title', 
     'copy'   => 'Hello', 
    ), 
    1 => Array (
     'category'  => 'body', 
     'sub-category' => 'intro', 
     'sub-sub-category' => 'footer', 
     'sub-sub-child-category' => 'right', 
     'id'   => 'title', 
     'copy'   => 'Bye', 
    ), 
); 

我想把它改造成

$example_output_1 = Array (
    'body' => Array (
     'intro' => Array (
      'header' => Array (
       'title' => 'Hello', 
      ), 
      'footer' => Array (
       'title' => 'Bye', 
      ), 
     ), 
    ), 
); 

$example_output_2 = Array (
    'body' => Array (
     'intro' => Array (
      'header' => Array ( 
       'left' => Array (
        'title' => 'Hello', 
       ), 
      ), 
      'footer' => Array (
       'right' => Array (
        'title' => 'Bye', 
       ) 
      ), 
     ), 
    ), 
); 

注意數組的深度是動態的(沒有設置 - 僅通過一次點擊「複製'它是否表示數組的深度)。

我有問題試圖正確地獲得遞歸。我使用的基本但非常粗略的算法是 - 循環遍歷行 - 遍歷行內容 - 當索引爲「複製」時,最終值爲當前值。 - 然後建立陣列

我設法讓它只處理一行數組,但它非常混亂,有點斑駁,所以我感覺我真的需要從頭開始。 更新:附加的要求令人尷尬的代碼(不要尖叫,P!)

function buildArray($row, $start = true) { 

    if ($start) { 
     $result = array(); 
    } 

    if (! is_array($row)) { 
     return $row; 
    } 

    // Get the first element of the array include its index 
    $cellValue = null; 
    $colId = null; 
    foreach($row AS $index => $value) { 
     $cellValue = $value; 
     $colId = $index; 
     break; 
    } 

    // Reduce the array by one 
    $tempRow = $row; 
    $temp = array_shift($tempRow); 

    if ($colId == 'copy') { 
     $result[$cell] = buildArray($cellValue, $locale, false); 
    } else { 
     $result[$cell] = buildArray($tempRow, $locale, false); 
    } 

    return $result; 
} 

任何幫助將不勝感激。

+2

聽起來很直截了當。你不能把你的算法描述變成實際的'foreach'循環嗎?否則,這種類似於* gimme teh codez *請求。我們想幫助你,而不是爲你工作;)再給它一次併發布結果。 – webbiedave

+2

感謝您發佈代碼。別煩惱。總是一個良好的學習經驗,與他人分享並獲得反饋。 – webbiedave

+0

大部分的遞歸性質可以通過使用'array_merge_recursive'來解決,其餘的都是尾遞歸的,所以可以迭代求解:) –

回答

1

這可以迭代解決,因爲遞歸只會發生在函數的尾部。以下代碼是簡化。它在迭代舊的時候構建一個新的分層數組。

轉換每個條目後,它將使用array_merge_recursive合併。

function transform($a) 
{ 
    // create new array and keep a reference to it 
    $b = array(); $cur = &$b; 
    foreach ($a as $key => $value) { 
     if ('id' === $key) { 
      // we're done, add value to the array built so far using id and copy 
      $cur[$value] = $a['copy']; 
      break; 
     } else { 
      // create one more level 
      $cur[$value] = array(); 
      // and update the reference 
      $cur = &$cur[$value]; 
     } 
    } 
    // all done 
    return $b; 
} 

// $example_2 is your multi-dimensional array 
$merged = call_user_func_array('array_merge_recursive', 
    array_map('transform', $example_2) 
); 
+0

感謝所有已回答的問題。這是一個艱難的決定,選擇哪個是最好的可接受的答案,因爲兩者都可以接受,但StackOverflow不會允許> 1答案。我選擇了這個作爲可接受的答案,因爲@Jack向我強調了關於array_merge_recursive函數,我沒有意識到存在。 – MechaStorm

3

應該很簡單:

$originalArray = array(); // <-- should contain your values 
$newArray = array(); 

foreach($originalArray as $item) 
{ 
    $category = $item['category']; 
    $subcategory = $item['sub-category']; 

    if (empty($newArray[$category])) 
    { 
     $newArray[$category] = array(); 
    } 
    if (empty($newArray[$category][$subcategory])) 
    { 
     $newArray[$category][$subcategory] = array(); 
    } 

    $newArray[$category][$subcategory][$item['id']] = $item['copy']; 
} 

在這裏看到它在行動:http://codepad.viper-7.com/9bDiLP


更新:現在你已經指定好需要的無限遞歸,這裏有一個射擊即:

$originalArray = array(); // <-- Your values go here 
$newArray = array(); 

foreach ($originalArray as $item) 
{ 
    $inception = &$newArray; // http://www.imdb.com/title/tt1375666/ 

    foreach ($item as $key => $val) 
    { 
     if ($key != 'id') 
     { 
      if (empty($inception[$val])) 
      { 
       $inception[$val] = array(); 
      } 
      $inception = &$inception[$val]; 
     } 
     else 
     { 
      $inception[ $val ] = $item['copy']; 
      break; 
     } 
    } 
} 

...這裏的演示:http://codepad.viper-7.com/F9hY7h

+0

謝謝你,我忘了補充說那只是輸入的一個例子,深度可以實際上是未知的(因此我爲什麼要嘗試遞歸) – MechaStorm

+0

@MechaStorm - 深層數組會持有什麼?你可以添加到你的問題? –

+0

+1在OP編輯它之前,完美地回答了這個問題。 – webbiedave