Как вы переиндексировать массив в PHP?
У меня есть следующий массив, который я хотел бы переиндексировать, чтобы ключи поменялись местами (в идеале, начиная с 1):
Текущий массив (правка: массив на самом деле выглядит так):
Array (
[2] => Object
(
[title] => Section
[linked] => 1
)
[1] => Object
(
[title] => Sub-Section
[linked] => 1
)
[0] => Object
(
[title] => Sub-Sub-Section
[linked] =>
)
)
Как это должно быть:
Array (
[1] => Object
(
[title] => Section
[linked] => 1
)
[2] => Object
(
[title] => Sub-Section
[linked] => 1
)
[3] => Object
(
[title] => Sub-Sub-Section
[linked] =>
)
)
19 ответов
Если вы хотите переиндексировать, начиная с нуля, просто сделайте следующее:
$iZero = array_values($arr);
Если вам нужно, чтобы начать с одного, то используйте следующее:
$iOne = array_combine(range(1, count($arr)), array_values($arr));
Вот справочные страницы для используемых функций:
array_values()
array_combine()
range()
Вот лучший способ:
# Array
$array = array('tomato', '', 'apple', 'melon', 'cherry', '', '', 'banana');
это возвращает
Array
(
[0] => tomato
[1] =>
[2] => apple
[3] => melon
[4] => cherry
[5] =>
[6] =>
[7] => banana
)
делая это
$array = array_values(array_filter($array));
Вы получаете это
Array
(
[0] => tomato
[1] => apple
[2] => melon
[3] => cherry
[4] => banana
)
объяснение
array_values()
Возвращает значения входного массива и численно индексирует.
array_filter()
: Фильтрует элементы массива с помощью определяемой пользователем функции (UDF Если ничего не указано, все записи во входной таблице со значением FALSE будут удалены.)
Я только что узнал, что вы также можете сделать
array_splice($ar, 0, 0);
Это делает переиндексацию на месте, поэтому вы не получите копию исходного массива.
Почему переиндексация? Просто добавьте 1 к индексу:
foreach ($array as $key => $val) {
echo $key + 1, '<br>';
}
Изменить После уточнения вопроса: вы можете использовать array_values
сбросить индекс, начиная с 0. Тогда вы можете использовать алгоритм, приведенный выше, если вы просто хотите, чтобы напечатанные элементы начинались с 1.
Вы можете переиндексировать массив, чтобы новый массив начинался с индекса 1, как здесь;
$arr = array(
'2' => 'red',
'1' => 'green',
'0' => 'blue',
);
$arr1 = array_values($arr); // Reindex the array starting from 0.
array_unshift($arr1, ''); // Prepend a dummy element to the start of the array.
unset($arr1[0]); // Kill the dummy element.
print_r($arr);
print_r($arr1);
Выход из вышесказанного есть;
Array
(
[2] => red
[1] => green
[0] => blue
)
Array
(
[1] => red
[2] => green
[3] => blue
)
Это будет делать то, что вы хотите:
<?php
$array = array(2 => 'a', 1 => 'b', 0 => 'c');
array_unshift($array, false); // Add to the start of the array
$array = array_values($array); // Re-number
// Remove the first index so we start at 1
$array = array_slice($array, 1, count($array), true);
print_r($array); // Array ( [1] => a [2] => b [3] => c )
?>
Вы можете подумать, почему вы вообще хотите использовать массив на основе 1. Массивы на основе нуля (при использовании неассоциативных массивов) довольно стандартны, и если вы хотите выводить данные в пользовательский интерфейс, большинство из них справится с решением, просто увеличив целое число при выводе в пользовательский интерфейс.
Подумайте о согласованности - как в вашем приложении, так и в коде, с которым вы работаете, - когда будете думать об индексаторах на основе 1 для массивов.
Самый быстрый способ, о котором я могу думать
array_unshift($arr, null);
unset($arr[0]);
print_r($arr);
И если вы просто хотите переиндексировать массив (начать с нуля) и у вас PHP +7.3, вы можете сделать это следующим образом
array_unshift($arr);
я полагаю array_unshift
Это лучше чем array_values
поскольку первый не создает копию массива.
Ну, я хотел бы думать, что для любой вашей конечной цели вам не нужно было бы модифицировать массив, чтобы он был основан на 1, а не на 0, но вместо этого мог бы обрабатывать его во время итерации, как написал Гамбо.
Однако, чтобы ответить на ваш вопрос, эта функция должна преобразовать любой массив в версию на основе 1
function convertToOneBased( $arr )
{
return array_combine( range( 1, count( $arr ) ), array_values( $arr ) );
}
РЕДАКТИРОВАТЬ
Вот более многоразовая / гибкая функция, если хотите
$arr = array( 'a', 'b', 'c' );
echo '<pre>';
print_r( reIndexArray( $arr ) );
print_r( reIndexArray( $arr, 1 ) );
print_r( reIndexArray( $arr, 2 ) );
print_r( reIndexArray( $arr, 10 ) );
print_r( reIndexArray( $arr, -10 ) );
echo '</pre>';
function reIndexArray( $arr, $startAt=0 )
{
return ( 0 == $startAt )
? array_values( $arr )
: array_combine( range( $startAt, count( $arr ) + ( $startAt - 1 ) ), array_values( $arr ) );
}
Более элегантное решение:
$list = array_combine(range(1, count($list)), array_values($list));
Как и @monowerker, мне нужно было переиндексировать массив, используя ключ объекта...
$new = array();
$old = array(
(object)array('id' => 123),
(object)array('id' => 456),
(object)array('id' => 789),
);
print_r($old);
array_walk($old, function($item, $key, &$reindexed_array) {
$reindexed_array[$item->id] = $item;
}, &$new);
print_r($new);
Это привело к:
Array
(
[0] => stdClass Object
(
[id] => 123
)
[1] => stdClass Object
(
[id] => 456
)
[2] => stdClass Object
(
[id] => 789
)
)
Array
(
[123] => stdClass Object
(
[id] => 123
)
[456] => stdClass Object
(
[id] => 456
)
[789] => stdClass Object
(
[id] => 789
)
)
$tmp = array();
foreach (array_values($array) as $key => $value) {
$tmp[$key+1] = $value;
}
$array = $tmp;
Такое ощущение, что все array_combine()
все ответы копируют одну и ту же "ошибку" (ненужный вызов array_values()
).
array_combine()
игнорирует ключи обоих параметров, которые он получает.
Код: (Демо)
$array = [
2 => (object)['title' => 'Section', 'linked' => 1],
1 => (object)['title' => 'Sub-Section', 'linked' => 1],
0 => (object)['title' => 'Sub-Sub-Section', 'linked' => null]
];
var_export(array_combine(range(1, count($array)), $array));
Выход:
array (
1 =>
(object) array(
'title' => 'Section',
'linked' => 1,
),
2 =>
(object) array(
'title' => 'Sub-Section',
'linked' => 1,
),
3 =>
(object) array(
'title' => 'Sub-Sub-Section',
'linked' => NULL,
),
)
Если вы не пытаетесь переупорядочить массив, вы можете просто сделать:
$ array = array_reverse ($ array);
$ array = array_reverse ($ array);
Массив array_reverse очень быстрый и меняет порядок при обратном. Кто-то еще показал мне это давным-давно. Так что я не могу взять кредит за то, что придумал это. Но это очень просто и быстро.
Подобно вкладу Ника, я пришел к тому же решению для переиндексации массива, но немного улучшил функцию, поскольку в PHP версии 5.4 она не работает из-за передачи переменных по ссылке. Пример функции переиндексации затем выглядит следующим образом: use
закрытие ключевых слов:
function indexArrayByElement($array, $element)
{
$arrayReindexed = [];
array_walk(
$array,
function ($item, $key) use (&$arrayReindexed, $element) {
$arrayReindexed[$item[$element]] = $item;
}
);
return $arrayReindexed;
}
Удаление дубликатов и переиндексация массива:
<?php
$oldArray = array('0'=>'php','1'=>'java','2'=>'','3'=>'asp','4'=>'','5'=>'mysql');
//duplicate removal
$fillteredArray = array_filter($oldArray);
//reindexing actually happens here
$newArray = array_merge($filteredArray);
print_r($newArray);
?>
Вы можете легко сделать это после совместного использования функций array_values () и array_filter () для удаления пустых элементов массива и переиндексации из массива в PHP.
Функция array_filter () Функция PHP array_filter() удаляет пустые элементы массива или значения из массива в PHP. Это также удалит пустые, нулевые, ложные, 0 (ноль) значения.
Функция array_values () Функция PHP array_values () возвращает массив, содержащий все значения массива. Возвращенный массив будет иметь числовые ключи, начиная с 0 и увеличиваясь на 1.
Удалить пустые элементы массива и переиндексировать
Сначала давайте посмотрим на вывод массива $stack:
<?php
$stack = array("PHP", "HTML", "CSS", "", "JavaScript", null, 0);
print_r($stack);
?>
Выход:
Array
(
[0] => PHP
[1] => HTML
[2] => CSS
[3] =>
[4] => JavaScript
[5] =>
[6] => 0
)
В приведенном выше выводе мы хотим удалить пустые, нулевые, 0 (нулевые) значения и затем переиндексировать элементы массива. Теперь мы будем использовать функции array_values () и array_filter (), как в следующем примере:
<?php
$stack = array("PHP", "HTML", "CSS", "", "JavaScript", null, 0);
print_r(array_values(array_filter($stack)));
?>
Выход:
Array
(
[0] => PHP
[1] => HTML
[2] => CSS
[3] => JavaScript
)
Вот моя собственная реализация. Ключи во входном массиве будут перенумерованы с приращением ключей, начиная с $start_index.
function array_reindex($array, $start_index)
{
$array = array_values($array);
$zeros_array = array_fill(0, $start_index, null);
return array_slice(array_merge($zeros_array, $array), $start_index, null, true);
}
Просто сделайте это:
<?php
array_push($array, '');
$array = array_reverse($array);
array_shift($array);
Сортировка - это всего лишь сортировка (), переиндексация кажется немного глупой, но если это необходимо, она сделает это. Хотя не на месте. Используйте array_walk(), если вы будете делать это в нескольких местах, просто используйте цикл for-key-value, если это одноразовая операция.
<?php
function reindex(&$item, $key, &$reindexedarr) {
$reindexedarr[$key+1] = $item;
}
$arr = Array (2 => 'c', 1 => 'b', 0 => 'a');
sort($arr);
$newarr = Array();
array_walk($arr, reindex, &$newarr);
$arr = $newarr;
print_r($arr); // Array ( [1] => a [2] => b [3] => c )
?>
Если все в порядке, чтобы создать новый массив, это так:
$result = array();
foreach ( $array as $key => $val )
$result[ $key+1 ] = $val;
Если вам нужно развернуть на месте, вам нужно запустить в обратном направлении, чтобы не топать по нужным вам индексам:
for ( $k = count($array) ; $k-- > 0 ; )
$result[ $k+1 ] = $result[ $k ];
unset( $array[0] ); // remove the "zero" element