PHP - 获取array_values以重新索引嵌套数组

时间:2013-11-01 16:30:54

标签: php multidimensional-array reindex

我已经为此寻找了一段时间的解决方案,但似乎无法让一个人工作。我有一个多维数组,并且能够使用array_values()成功地将“父”数组项重新索引为0(它们被索引为1并且JSON将其视为对象而不是数组)。但是,嵌套数组也需要从0重新索引,我似乎无法让它工作。这是我目前通过array_values($arr)收到的信息:

array (
  0 => 
  array (
    'navigationMenuId' => '1',
    'parentNavigationMenuId' => '0',
    'contentId' => '1',
    'fullURL' => '/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Index',
    'navigationAnchor' => 'Home',
    'navigationOrder' => '1',
    'subNavigationItems' => 
    array (
    ),
  ),
  1 => 
  array (
    'navigationMenuId' => '2',
    'parentNavigationMenuId' => '0',
    'contentId' => '15',
    'fullURL' => '/top-nav-1/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Index',
    'navigationAnchor' => 'Top Nav 1',
    'navigationOrder' => '2',
    'subNavigationItems' => 
    array (
    ),
  ),
  2 => 
  array (
    'navigationMenuId' => '3',
    'parentNavigationMenuId' => '0',
    'contentId' => '7',
    'fullURL' => '/top-nav-2/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Index',
    'navigationAnchor' => 'Top Nav 2',
    'navigationOrder' => '3',
    'subNavigationItems' => 
    array (
      4 => 
      array (
        'navigationMenuId' => '4',
        'parentNavigationMenuId' => '3',
        'contentId' => '8',
        'fullURL' => '/top-nav-2/sub-nav-1',
        'contentSlug' => 'sub-nav-1',
        'contentAlias' => 'Sub Nav 1',
        'navigationAnchor' => 'Sub Nav 1',
        'navigationOrder' => '1',
        'subNavigationItems' => 
        array (
        ),
      ),
      5 => 
      array (
        'navigationMenuId' => '5',
        'parentNavigationMenuId' => '3',
        'contentId' => '10',
        'fullURL' => '/top-nav-2/sub-nav-2',
        'contentSlug' => 'sub-nav-2',
        'contentAlias' => 'Sub Nav 2',
        'navigationAnchor' => 'Sub Nav 2',
        'navigationOrder' => '2',
        'subNavigationItems' => 
        array (
        ),
      ),
      6 => 
      array (
        'navigationMenuId' => '6',
        'parentNavigationMenuId' => '3',
        'contentId' => '9',
        'fullURL' => '/top-nav-2/sub-nav-3',
        'contentSlug' => 'sub-nav-3',
        'contentAlias' => 'Sub Nav 3',
        'navigationAnchor' => 'Sub Nav 3',
        'navigationOrder' => '3',
        'subNavigationItems' => 
        array (
        ),
      ),
      7 => 
      array (
        'navigationMenuId' => '7',
        'parentNavigationMenuId' => '3',
        'contentId' => '11',
        'fullURL' => '/top-nav-2/sub-nav-4',
        'contentSlug' => 'sub-nav-4',
        'contentAlias' => 'Sub Nav 4',
        'navigationAnchor' => 'Sub Nav 4',
        'navigationOrder' => '4',
        'subNavigationItems' => 
        array (
        ),
      ),
    ),
  ),
  3 => 
  array (
    'navigationMenuId' => '8',
    'parentNavigationMenuId' => '0',
    'contentId' => '5',
    'fullURL' => '/top-nav-3/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Top Nav 3',
    'navigationAnchor' => 'Top Nav 3',
    'navigationOrder' => '4',
    'subNavigationItems' => 
    array (
    ),
  ),
  4 => 
  array (
    'navigationMenuId' => '9',
    'parentNavigationMenuId' => '0',
    'contentId' => '6',
    'fullURL' => '/top-nav-4/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Top Nav 4',
    'navigationAnchor' => 'Top Nav 4',
    'navigationOrder' => '5',
    'subNavigationItems' => 
    array (
      10 => 
      array (
        'navigationMenuId' => '10',
        'parentNavigationMenuId' => '9',
        'contentId' => '12',
        'fullURL' => '/top-nav-4/sub-nav-1',
        'contentSlug' => 'sub-nav-1',
        'contentAlias' => 'Sub Nav 1',
        'navigationAnchor' => 'Sub Nav 1',
        'navigationOrder' => '1',
        'subNavigationItems' => 
        array (
        ),
      ),
      11 => 
      array (
        'navigationMenuId' => '11',
        'parentNavigationMenuId' => '9',
        'contentId' => '13',
        'fullURL' => '/top-nav-4/sub-nav-2',
        'contentSlug' => 'sub-nav-2',
        'contentAlias' => 'Sub Nav 2',
        'navigationAnchor' => 'Sub Nav 2',
        'navigationOrder' => '2',
        'subNavigationItems' => 
        array (
        ),
      ),
      12 => 
      array (
        'navigationMenuId' => '12',
        'parentNavigationMenuId' => '9',
        'contentId' => '14',
        'fullURL' => '/top-nav-4/sub-nav-3',
        'contentSlug' => 'sub-nav-3',
        'contentAlias' => 'Sub Nav 3',
        'navigationAnchor' => 'Sub Nav 3',
        'navigationOrder' => '3',
        'subNavigationItems' => 
        array (
        ),
      ),
    ),
  ),
  5 => 
  array (
    'navigationMenuId' => '13',
    'parentNavigationMenuId' => '0',
    'contentId' => '4',
    'fullURL' => '/top-nav-5/index',
    'contentSlug' => 'index',
    'contentAlias' => 'Top Nav 5',
    'navigationAnchor' => 'Top Nav 5',
    'navigationOrder' => '6',
    'subNavigationItems' => 
    array (
    ),
  ),
)

注意第一个嵌套数组索引是4,5,6和7,第二个索引是10,11和12.我需要它们从0开始。如果执行此操作的函数可以是无限递归函数。如果你看到每个项目都有一个subNavigationItems数组,可能会被更多东西填充,我也需要将这些数组重新索引为0。

有关如何实现这一目标的任何想法?

3 个答案:

答案 0 :(得分:4)

使用此

<?php 

    function reOrderArray($array) {
        if(! is_array($array)) {
             return $array;
        }
        $count = 0;
        $result = array();
        foreach($array as $k => $v) {
            if(is_integer_value($k)) {
               $result[$count] = reOrderArray($v);
               ++$count;
            } else {
              $result[$k] = reOrderArray($v);
            }
        }
        return $result;
    }

    public function is_integer_value($value) {
        if(!is_int($value)) {
            if(is_string($value) && preg_match("/^-?\d+$/i",$value)) {
                return true;
            }
            return false;
        }
        return true;
    }

答案 1 :(得分:0)

我认为应该这样做:

function reindex_array_recursive($array) {
    if (is_array($array)) {
        if (array_keys($array) === range(0, count($array) - 1)) { // Indexed array
            return array_values(array_map('reindex_array_recursive', $array));
        } else { // Associative array
            foreach ($array as $value) {
                $value = reindex_array_recursively($value);
            }
            return $array;
        }
    } else {
        return $array;
    }
}

它不会递归到对象中,只会递归到子数组中。

答案 2 :(得分:-1)

可预测地,子数组放置在subNavigationItems键控元素中,因此不必检查每个级别中每个元素的数据类型。

array_values()的递归调用仅在subNavigationItems上且仅当它不为空时才需要调用。

以下内容比其他答案要干净得多,并且功能开销也较小。

代码:(Demo

function reindexChildren(array $array): array {
    foreach ($array as &$item) {
        if ($item['subNavigationItems']) {
            $item = reindexChildren($item['subNavigationItems']);
        }
    }
    return array_values($array);
}

var_export(
    reindexChildren($menu)
);