PHP - получить array_values для переиндексации вложенных массивов
Я некоторое время искал решение для этого, но, похоже, не смог заставить его работать. У меня есть многомерный массив, и я смог успешно переименовать элементы родительского массива в 0 (они были проиндексированы в 1, а JSON рассматривал его как объект вместо массива), используя array_values()
, ОДНАКО, вложенные массивы также должны быть переиндексированы с 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.
Любые мысли о том, как я могу это сделать?
2 ответа
Использовать этот
<?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;
}
Я думаю, что это должно сделать это:
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;
}
}
Он не превращается в объекты, только в подмассивы.
Дочерние массивы предсказуемо помещаются в
subNavigationItems
ключевые элементы, поэтому нет необходимости проверять тип данных каждого элемента на каждом уровне.
Рекурсивный вызов
array_values()
для повторного индексирования ключей необходимо вызывать только
subNavigationItems
и только если он не пустой.
Следующие ответы заметно чище и имеют меньше функциональных накладных расходов, чем другие ответы.
Код: (Демо)
function reindexChildren(array $array): array {
foreach ($array as &$item) {
if ($item['subNavigationItems']) {
$item = reindexChildren($item['subNavigationItems']);
}
}
return array_values($array);
}
var_export(
reindexChildren($menu)
);