У меня есть следующий массив, который я хотел бы переиндексировать, чтобы клавиши были отменены (в идеале начиная с 1):
Текущий массив ( edit: массив действительно выглядит так):
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] => ) )
Если вы хотите повторно индексировать начало до нуля, просто выполните следующие действия:
$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, будут удалены .)
Почему переиндексация? Просто добавьте 1 к индексу:
foreach ($array as $key => $val) { echo $key + 1, '<br>'; }
Изменить После того, как вопрос выяснен: вы можете использовать array_values
для сброса индекса, начинающегося с 0. Затем вы можете использовать вышеприведенный алгоритм, если хотите, чтобы печатные элементы начинались с 1.
Я только что узнал, что вы также можете сделать
array_splice($ar, 0, 0);
Это делает повторное индексирование на месте, поэтому вы не получаете копию исходного массива.
Ну, я бы хотел подумать, что для какой бы цели вы ни выбрали, вам фактически не нужно было бы изменять массив, чтобы он был основан на 1, а не на основе 0, но вместо этого мог обрабатывать его во время итерации, как опубликовал Gumbo.
Однако , чтобы ответить на ваш вопрос, эта функция должна преобразовывать любой массив в 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 ) ); }
Это сделает то, что вы хотите:
<?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 ) ?>
Более элегантное решение:
$ list = array_combine (диапазон (1, count ($ list)), array_values ($ list));
Возможно, вам захочется рассмотреть, почему вы хотите использовать массив на основе 1. Массивы с нулевым значением (при использовании неассоциативных массивов) довольно стандартизированы, и если вы хотите выводить на пользовательский интерфейс, большинство из них будет обрабатывать решение, просто увеличивая целое число после вывода в пользовательский интерфейс.
Подумайте о согласованности – как в своем приложении, так и в коде, с которым вы работаете, – когда думаете о индексаторах на основе 1 для массивов.
Подобно @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;
Вы можете переиндексировать массив, чтобы новый массив начинался с индекса 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);
с$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 )
Если вы не пытаетесь изменить порядок массива, вы можете просто сделать:
$ array = array_reverse ($ array);
$ array = array_reverse ($ array);
Массив_реверс очень быстрый, и он меняет порядок, когда он меняет направление. Кто-то еще показал мне это давным-давно. Поэтому я не могу смириться с этим. Но это очень просто и быстро.
дублировать удаление и переиндексировать массив:
<?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); ?>
Сортировка – это просто sort () , переиндексирование кажется немного глупым, но если это необходимо, это сделает это. Хотя и не на месте. Используйте 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 ) ?>
Подобно вкладу Ника, я пришел к тому же решению для переиндексации массива, но немного увеличил эту функцию с PHP версии 5.4, это не работает из-за передачи переменных по ссылке. Например, функция переиндексирования используется, use
закрытие ключевого слова use
:
function indexArrayByElement($array, $element) { $arrayReindexed = []; array_walk( $array, function ($item, $key) use (&$arrayReindexed, $element) { $arrayReindexed[$item[$element]] = $item; } ); return $arrayReindexed; }
Вот моя собственная реализация. Ключи входного массива будут перенумерованы с добавочными ключами, начиная с $ 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); }
Если это нормально, то создайте новый массив:
$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