How do you reindex an array in PHP but with indexes starting from 1?
PhpArraysIndexingPhp Problem Overview
I have the following array, which I would like to reindex so the keys are reversed (ideally starting at 1):
Current array (edit: the array actually looks like this):
Array (
[2] => Object
(
[title] => Section
[linked] => 1
)
[1] => Object
(
[title] => Sub-Section
[linked] => 1
)
[0] => Object
(
[title] => Sub-Sub-Section
[linked] =>
)
)
How it should be:
Array (
[1] => Object
(
[title] => Section
[linked] => 1
)
[2] => Object
(
[title] => Sub-Section
[linked] => 1
)
[3] => Object
(
[title] => Sub-Sub-Section
[linked] =>
)
)
Php Solutions
Solution 1 - Php
If you want to re-index starting to zero, simply do the following:
$iZero = array_values($arr);
If you need it to start at one, then use the following:
$iOne = array_combine(range(1, count($arr)), array_values($arr));
Here are the manual pages for the functions used:
Solution 2 - Php
Here is the best way:
# Array
$array = array('tomato', '', 'apple', 'melon', 'cherry', '', '', 'banana');
that returns
Array
(
[0] => tomato
[1] =>
[2] => apple
[3] => melon
[4] => cherry
[5] =>
[6] =>
[7] => banana
)
by doing this
$array = array_values(array_filter($array));
you get this
Array
(
[0] => tomato
[1] => apple
[2] => melon
[3] => cherry
[4] => banana
)
Explanation
array_values()
: Returns the values of the input array and indexes numerically.
array_filter()
: Filters the elements of an array with a user-defined function (UDF If none is provided, all entries in the input table valued FALSE will be deleted.)
Solution 3 - Php
I just found out you can also do a
array_splice($ar, 0, 0);
That does the re-indexing inplace, so you don't end up with a copy of the original array.
Solution 4 - Php
Why reindexing? Just add 1 to the index:
foreach ($array as $key => $val) {
echo $key + 1, '<br>';
}
Edit After the question has been clarified: You could use the array_values
to reset the index starting at 0. Then you could use the algorithm above if you just want printed elements to start at 1.
Solution 5 - Php
Well, I would like to think that for whatever your end goal is, you wouldn't actually need to modify the array to be 1-based as opposed to 0-based, but could instead handle it at iteration time like Gumbo posted.
However, to answer your question, this function should convert any array into a 1-based version
function convertToOneBased( $arr )
{
return array_combine( range( 1, count( $arr ) ), array_values( $arr ) );
}
EDIT
Here's a more reusable/flexible function, should you desire it
$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 ) );
}
Solution 6 - Php
This will do what you want:
<?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 )
?>
Solution 7 - Php
You may want to consider why you want to use a 1-based array at all. Zero-based arrays (when using non-associative arrays) are pretty standard, and if you're wanting to output to a UI, most would handle the solution by just increasing the integer upon output to the UI.
Think about consistency—both in your application and in the code you work with—when thinking about 1-based indexers for arrays.
Solution 8 - Php
A more elegant solution:
$list = array_combine(range(1, count($list)), array_values($list));
Solution 9 - Php
You can reindex an array so the new array starts with an index of 1 like this;
$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);
The output from the above is;
Array
(
[2] => red
[1] => green
[0] => blue
)
Array
(
[1] => red
[2] => green
[3] => blue
)
Solution 10 - Php
Similar to @monowerker, I needed to reindex an array using an object's key...
$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);
This resulted in:
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
)
)
Solution 11 - Php
$tmp = array();
foreach (array_values($array) as $key => $value) {
$tmp[$key+1] = $value;
}
$array = $tmp;
Solution 12 - Php
If you are not trying to reorder the array you can just do:
$array = array_reverse( $array );
$array = array_reverse( $array );
The array_reverse is very fast and it reorders as it reverses. Someone else showed me this a long time ago. So I can't take credit for coming up with it. But it is very simple and fast.
Solution 13 - Php
Similar to Nick's contribution, I came to the same solution for reindexing an array, but enhanced the function a little since from PHP version 5.4, it doesn't work because of passing variables by reference. Example reindexing function is then like this using use
keyword closure:
function indexArrayByElement($array, $element)
{
$arrayReindexed = [];
array_walk(
$array,
function ($item, $key) use (&$arrayReindexed, $element) {
$arrayReindexed[$item[$element]] = $item;
}
);
return $arrayReindexed;
}
Solution 14 - Php
The fastest way I can think of
array_unshift($arr, null);
unset($arr[0]);
print_r($arr);
And if you just want to reindex the array(start at zero) and you have PHP +7.3 you can do it this way
array_unshift($arr);
I believe array_unshift
is better than array_values
as the former does not create a copy of the array.
Solution 15 - Php
Duplicate removal and reindex an 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);
?>
Solution 16 - Php
Here's my own implementation. Keys in the input array will be renumbered with incrementing keys starting from $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);
}
Solution 17 - Php
Simply do this:
<?php
array_push($array, '');
$array = array_reverse($array);
array_shift($array);
Solution 18 - Php
You can easily do it after use array_values() and array_filter() function together to remove empty array elements and reindex from an array in PHP.
array_filter() function The PHP array_filter() function remove empty array elements or values from an array in PHP. This will also remove blank, null, false, 0 (zero) values.
array_values() function The PHP array_values() function returns an array containing all the values of an array. The returned array will have numeric keys, starting at 0 and increase by 1.
Remove Empty Array Elements and Reindex
First let’s see the $stack array output :
<?php
$stack = array("PHP", "HTML", "CSS", "", "JavaScript", null, 0);
print_r($stack);
?>
Output:
Array
(
[0] => PHP
[1] => HTML
[2] => CSS
[3] =>
[4] => JavaScript
[5] =>
[6] => 0
)
In above output we want to remove blank, null, 0 (zero) values and then reindex array elements. Now we will use array_values() and array_filter() function together like in below example:
<?php
$stack = array("PHP", "HTML", "CSS", "", "JavaScript", null, 0);
print_r(array_values(array_filter($stack)));
?>
Output:
Array
(
[0] => PHP
[1] => HTML
[2] => CSS
[3] => JavaScript
)
Solution 19 - Php
It feels like all of the array_combine()
answers are all copying the same "mistake" (the unnecessary call of array_values()
).
array_combine()
ignores the keys of both parameters that it receives.
Code: (Demo)
$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));
Output:
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,
),
)
Solution 20 - Php
Sorting is just a sort(), reindexing seems a bit silly but if it is needed this will do it. Though not in-place. Use array_walk() if you will do this in a bunch of places, just use a for-key-value loop if this is a one-time operation.
<?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 )
?>
Solution 21 - Php
If it's OK to make a new array it's this:
$result = array();
foreach ( $array as $key => $val )
$result[ $key+1 ] = $val;
If you need reversal in-place, you need to run backwards so you don't stomp on indexes that you need:
for ( $k = count($array) ; $k-- > 0 ; )
$result[ $k+1 ] = $result[ $k ];
unset( $array[0] ); // remove the "zero" element