2

我在循環下面的數組,其中有多個條目。在這個例子中,我有3個元素,其中每個元素都有3個值。變換層次數組中的簡單數組

[0] 
    ['name'] => 'aaa' 
    ['id'] => 38679 
    ['parent-id'] => 0 
[1] 
    ['name'] => 'bbb' 
    ['id'] => 38830 
    ['parent-id'] => 38679 
[2] 
    ['name'] => 'ccc' 
    ['id'] => 38680 
    ['parent-id'] => 38830 

因此,循環槽數組,我需要構建一個又一個以這種格式(這個想法是構建層次):

[0] 
    [38679] => 'aaa' 
      [38830] => 'bbb' 
       [38680] => 'ccc' 

也許有另一種方式來做到這一點。任何建議都會很棒。

+0

這不是層次結構,目前還不清楚是什麼你想得到。你想要的數組背後的邏輯是什麼?基於'id'和'parent-id'元素的*層級*就像'aaa - > bbb - > ccc',其中'bbb'是'aaa'的子元素等等。這是你想要的嗎? – Timofey

+0

你是對的Timofey,我的陣列錯了。我編輯了這個問題。 – zephirus

回答

1

一個可能的解決方案是使用遞歸函數:

$test = [ 
    0 => [ 
     'name' => 'aaa', 
     'id' => 38679, 
     'parent-id' => 0 
    ], 
    1 => [ 
     'name' => 'bbb', 
     'id' => 38830, 
     'parent-id' => 38679 
    ], 
    2 => [ 
     'name' => 'ccc', 
     'id' => 38680, 
     'parent-id' => 38830 
    ] 
]; 

function make_hierarchy(array $arr, $parent = 0) { 
    $result = array(); 

    foreach($arr as $item) { 
     if ($item['parent-id'] == $parent) { 
      $children = make_hierarchy($arr, $item['id']); 
      $child = $item; 
      if ($children) { 
       $child['children'] = $children; 
      } 
      $result[] = $child; 
     } 
    } 
    return $result; 
} 

$r = make_hierarchy($test); 

var_dump($r); 
+0

'$ result [] = $ child;'給出錯誤 - '$ child'沒有聲明。 – trincot

+0

對不起,修正了錯誤。 – Timofey

+0

代碼現在運行,但輸出沒有任何id屬性,也沒有數組的索引對應於id值。不知何故,'ccc'節點丟失。結果只有兩個具有名稱屬性的節點('aaa'和'bbb')。 – trincot

1

迭代求解:

// set up test data 
$arr = [ 
    0 => [ 
     'name' => 'aaa', 
     'id' => 38679, 
     'parent-id' => 0 
     ], 
    1 => [ 
     'name' => 'bbb', 
     'id' => 38830, 
     'parent-id' => 38679 
     ], 
    2 => [ 
     'name' => 'ccc', 
     'id' => 38680, 
     'parent-id' => 38830 
     ] 
    ]; 

// hierarchy array that will have the result 
$hier = []; 

// Start off by putting all nodes as top-level nodes in the hierarchy 
foreach ($arr as $node) { 
    $node['children'] = []; 
    $hier[$node['id']] = $node; 
}; 

// Iterate to move nodes from the top-level under their respective parents. 
do { 
    $count = count($hier); 
    echo 'Next iteration: ', $count, ' top-level nodes left<br>'; 

    // Collect the ids of parents of top-level nodes 
    $parents = []; 
    foreach ($hier as $node) { 
     $parents[$node['parent-id']] = 1; 
    } 

    // Find all nodes that are candidate to be moved  
    foreach ($hier as $node) { 
     // Treat node only if it has gathered all of its children 
     if (!array_key_exists($node['id'], $parents)) { 
      $parentId = $node['parent-id']; 
      // Remove the parent-id attribute, it is not needed anymore 
      unset($node['parent-id']); 
      // Remove the node from the top-level 
      unset($hier[$node['id']]); 
      // Check that referenced parent exists, parent-id=0 will fail this. 
      if (array_key_exists($parentId, $hier)) { 
       // Move this node under its parent node, keyed by its ID 
       echo 'Node ', $node['id'], ' moved under ', $parentId, '<br>'; 
       $hier[$parentId]['children'][$node['id']] = $node; 
      } else { 
       // Node is stays on top-level (but without parent-id property): 
       echo 'Node ', $node['id'], ' stays at top level<br>'; 
       $hier[] = $node; 
      } 
     } 
    }; 
    // keep going as long as we were able to move at least one node 
} while (count($hier) < $count); 

echo 'Done. <pre>';  
print_r($hier); 
echo '</pre>';  

測試,並輸出:

Next iteration: 3 top-level nodes left 
Node 38680 moved under 38830 
Next iteration: 2 top-level nodes left 
Node 38830 moved under 38679 
Next iteration: 1 top-level nodes left 
Node 38679 stays at top level 
Done. 

Array 
(
    [38831] => Array 
     (
      [name] => aaa 
      [id] => 38679 
      [children] => Array 
       (
        [38830] => Array 
         (
          [name] => bbb 
          [id] => 38830 
          [children] => Array 
           (
            [38680] => Array 
             (
              [name] => ccc 
              [id] => 38680 
              [children] => Array 
               (
               ) 
             ) 
           ) 
         ) 
       ) 
     ) 
)