2016-12-28 75 views
0

我有一個存儲無限嵌套水平數組與不需要的額外數據。php重新格式化嵌套數組

$arr = array(
    array(
     'name' => 'item1', 
     'level' => 0, 
     'extra_key' => 'some_data', 
     'children' => array(
      'name' => 'sub-item1', 
      'level' => 1, 
      'extra_key' => 'some_data', 
      'children' => array(
       'name' => 'sub-sub-item1', 
       'level' => 2, 
       'extra_key' => 'some_data', 
       'children' => array() 
      ), 
      array(
       'name' => 'sub-sub2-item1', 
       'level' => 2, 
       'extra_key' => 'some_data', 
       'children' => array() 
      ), 
     ) 
    ), 
    array(
     'name' => 'item2', 
     'level' => 0, 
     'extra_key' => 'some_data', 
     'children' => array(
      'name' => 'sub-item2', 
      'level' => 2, 
      'extra_key' => 'some_data', 
      'children' => array(
       'name' => 'sub-sub-item2', 
       'level' => 2, 
       'extra_key' => 'some_data', 
       'children' => array() 
      ), 
      array(
       'name' => 'sub-sub2-item2', 
       'level' => 2, 
       'extra_key' => 'some_data', 
       'children' => array() 
      ), 
     ) 
    ), 
    array(
     'name' => 'item3', 
     'level' => 0, 
     'extra_key' => 'some_data', 
     'children' => array(
      'name' => 'sub-item3', 
      'level' => 1, 
      'extra_key' => 'some_data', 
      'children' => array(
       'name' => 'sub-sub-item3', 
       'level' => 2, 
       'extra_key' => 'some_data', 
       'children' => array() 
      ), 
      array(
       'name' => 'sub-sub2-item3', 
       'level' => 2, 
       'extra_key' => 'some_data', 
       'children' => array() 
      ), 
     ) 
    ), 
); 

預計輸出數組:

$arr = array(
    array(
     'name' => 'item1', 
     'nodes' => array(
      'name' => 'sub-item1', 
      'nodes' => array(
       'name' => 'sub-sub-item1', 
       'nodes' => array() 
      ), 
      array(
       'name' => 'sub-sub2-item1', 
       'nodes' => array() 
      ), 
     ) 
    ), 
    array(
     'name' => 'item2', 
     'nodes' => array(
      'name' => 'sub-item2', 
      'nodes' => array(
       'name' => 'sub-sub-item2', 
       'nodes' => array() 
      ), 
      array(
       'name' => 'sub-sub2-item2', 
       'nodes' => array() 
      ), 
     ) 
    ), 
    array(
     'name' => 'item3', 
     'nodes' => array(
      'name' => 'sub-item3', 
      'nodes' => array(
       'name' => 'sub-sub-item3', 
       'nodes' => array() 
      ), 
      array(
       'name' => 'sub-sub2-item3', 
       'nodes' => array() 
      ), 
     ) 
    ) 
); 

我想刪除像levelextra_key從各級不必要的按鍵,我想也更改密鑰childrennodes的名稱,然後複製同一陣列與相同的結構與新的格式。

我該如何做到這一點?

我試圖通過遞歸函數來做到這一點,但我沒能複製相同structrue

+0

array_walk_recursive閱讀關於這個在php.net上 –

+0

你能告訴我們你會期望作爲輸出數組是什麼? – zsram

+0

@zsram我編輯了問題以添加預期的輸出數組 – semsem

回答

1

您的結構是沒有意義的,可能是因爲你無法寫遞歸函數。如果有可能改變結構,我會建議這一個(與重新格式化功能實現):

<?php 

$actual = array(
    array(
     'name' => 'item1', 
     'level' => 0, 
     'extra_key' => 'some_data', 
     'children' => array(
      array(
       'name' => 'sub-item1', 
       'level' => 1, 
       'extra_key' => 'some_data', 
       'children' => array(
        array(
         'name' => 'sub-sub-item1', 
         'level' => 2, 
         'extra_key' => 'some_data', 
         'children' => array() 
        ), 
        array(
         'name' => 'sub-sub2-item1', 
         'level' => 2, 
         'extra_key' => 'some_data', 
         'children' => array() 
        ), 
       ) 
      ), 
     ) 
    ), 
); 

$expected = array(
    array(
     'name' => 'item1', 
     'nodes' => array(
      array(
       'name' => 'sub-item1', 
       'nodes' => array(
        array(
         'name' => 'sub-sub-item1', 
         'nodes' => array() 
        ), 
        array(
         'name' => 'sub-sub2-item1', 
         'nodes' => array() 
        ), 
       ), 
      ), 
     ) 
    ), 
); 

function change_array($original) 
{ 
    return array_map('change_node', $original); 
} 

function change_node($node) 
{ 
    return [ 
     'name' => $node['name'], 
     'nodes' => array_map('change_node', $node['children']), 
    ]; 
} 

var_dump($expected === change_array($actual)); 
+0

謝謝,完美無缺! – semsem

1

此函數將做你想要的遞歸。 如果需要,您可以添加額外的排除和/或重命名的索引;

function parseArray($array): array 
{ 
    // The resulting array 
    $result   = []; 
    // Indices you want renamed [`from` => `to`] 
    $renameIndices = ['children' => 'nodes']; 
    // Indices you want excluded [`1`, `2`] 
    $excludedIndices = ['level', 'extra_key']; 
    foreach ($array as $idx => $content) 
    { 
     // If excluded, continue (skip) node. 
     if (in_array($idx, $excludedIndices, true)) 
     { 
      continue; 
     } 
     // Setting the resulting (new) index. 
     $resultIdx = $idx; 
     // Check if this index should be renamed 
     if (array_key_exists($idx, $renameIndices)) 
     { 
      // If index should be renamed, apply new name 
      $resultIdx = $renameIndices[$idx]; 
     } 
     // If this content block is an array. Parse it. 
     if (is_array($content)) 
     { 
      $content = parseArray($content); 
     } 
     // Save content to resulting array. 
     $result[$resultIdx] = $content; 
    } 

    return $result; 
} 
+0

謝謝 請仔細閱讀@Anton Serdyuk repy here http://stackoverflow.com/a/41364381/1344637 – semsem