Как вы переиндексируете массив в PHP?

У меня есть следующий массив, который я хотел бы переиндексировать, чтобы клавиши были отменены (в идеале начиная с 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