46

I have values in some array I want to re index the whole array such that the the first value key should be 1 instead of zero i.e.

By default in PHP the array key starts from 0. i.e. 0 => a, 1=> b, I want to reindex the whole array to start from key = 1 i.e 1=> a, 2=> b, ....

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Khurram Ijaz
  • 1,844
  • 5
  • 24
  • 43
  • 4
    Is there any reason you can't just use a zero based array? – Jacob Mar 21 '11 at 05:45
  • @Jacob, for instance, a for loop that uses `% == 0` to define `` and `` tags. An `$i[0]` trips the ``. Anyway, that's how I ended up at this question :) – JoshP Dec 12 '13 at 15:19
  • Why are there so many upvotes on this question? What's wrong with 0-based index? – Fr0zenFyr Feb 20 '19 at 09:22

12 Answers12

58
$alphabet = array("a", "b", "c");
array_unshift($alphabet, "phoney");
unset($alphabet[0]);

Edit: I decided to benchmark this solution vs. others posed in this topic. Here's the very simple code I used:

$start = microtime(1);
for ($a = 0; $a < 1000; ++$a) {
    $alphabet = array("a", "b", "c");
    array_unshift($alphabet, "phoney");
    unset($alphabet[0]);
}
echo (microtime(1) - $start) . "\n";


$start = microtime(1);
for ($a = 0; $a < 1000; ++$a) {
    $stack = array('a', 'b', 'c');
    $i= 1;
    $stack2 = array();
    foreach($stack as $value){
        $stack2[$i] = $value;
        $i++;
    }
    $stack = $stack2;
}
echo (microtime(1) - $start) . "\n";


$start = microtime(1);
for ($a = 0; $a < 1000; ++$a) {
    $array = array('a','b','c');

    $array = array_combine(
        array_map(function($a){
            return $a + 1;
        }, array_keys($array)),
        array_values($array)
    );
}
echo (microtime(1) - $start) . "\n";

And the output:

0.0018711090087891
0.0021598339080811
0.0075368881225586
Michael McTiernan
  • 5,153
  • 2
  • 25
  • 16
  • FYI, In 2nd approach, `$i= 1; foreach($stack1 as $value){ $stack2[$i] = $value; $i++; }` will not perform same as `foreach ($stack1 as $k => $val) { $stack2[$k+1] = $val; }`. – Fr0zenFyr Feb 20 '19 at 09:21
  • I thanks to your answer. But, I am facing a problem as I use to get the length of the data(array), It alerts undefined in js. What should i use? –  Sep 27 '21 at 08:55
56

Here is my suggestion:

<?php
$alphabet = array(1 => 'a', 'b', 'c', 'd');
echo '<pre>';
print_r($alphabet);
echo '</pre>';
?>

The above example will output:

Array
(
    [1] => a
    [2] => b
    [3] => c
    [4] => d
)
Ricardo Miguel
  • 899
  • 11
  • 15
  • 5
    Your response ignores that we can not arbitrarily choose the index! Otherwise, the problem was not there! – Mirko Pagliai Aug 02 '14 at 13:23
  • Also this solution ignores, that sometimes array is generated dynamically and passed to variable, so we cannot access the first key without additional unnecessary code. – Boolean_Type Nov 06 '17 at 12:09
32

Simply try this

$array = array("a","b","c");
array_unshift($array,"");
unset($array[0]);
Shameer
  • 3,036
  • 1
  • 21
  • 27
11

Ricardo Miguel's solution works best when you're defining your array and want the first key to be 1. But if your array is already defined or gets put together elsewhere (different function or a loop) you can alter it like this:

$array = array('a', 'b', 'c'); // defined elsewhere

$array = array_filter(array_merge(array(0), $array));

array_merge will put an array containing 1 empty element and the other array together, re-indexes it, array_filter will then remove the empty array elements ($array[0]), making it start at 1.

kasimir
  • 1,506
  • 1
  • 20
  • 26
  • 5
    No, this is a wrong solution, `array_filter` will remove all empty values, not only the merged element. For example, if `$array = array('a', 'b', '');`, you will lose the 3rd element, which should be retained. – Fishdrowned Jun 07 '17 at 12:49
  • 1
    @Fishdrowned It is not meant to be a general purpose solution. – blackmambo Jan 04 '20 at 14:38
  • This is definitely not something that I would use. Not only does it risk damaging other data in the array because `array_filter()` is evaluating values and destorying all falsey elements; `array_filter()` is going to execute a check on every element in the array. – mickmackusa Aug 03 '22 at 23:12
10
$array = array('a', 'b', 'c', 'd');
$array = array_combine(range(1, count($array)), array_values($array));
print_r($array);

the result:

Array
(
    [1] => a
    [2] => b
    [3] => c
    [4] => d
)
Xin Guo
  • 111
  • 1
  • 4
6

If you are using a range, try this code:

$data = array_slice(range(0,12), 1, null, true);

// Array ( [1] => 1 [2] => 2 [3] => 3 [4] => 4 [5] => 5 [6] => 6 [7] => 7 [8] => 8 [9] => 9 [10] => 10 [11] => 11 [12] => 12 )
axiom82
  • 636
  • 1
  • 7
  • 15
  • Because the asker says `I have values in some array`, this answer is not a viable solution. This answer only works if you are populating a new array. – mickmackusa Aug 03 '22 at 23:10
1

I see this answer is very old, but my solution for this is by adding a +1 to your index. I'll do that because I think this is much faster and easy to read. When you print this it will start from 1 because 0+1 =1, then 2 etc.

  foreach($items as $index => $item){
 echo $index+1 . $item
}
Hos
  • 41
  • 4
0

I think it is simple as that:

$x = array("a","b","c");
$y =array_combine(range(1, count($x)), $x);
print_r($y);
Hardood
  • 503
  • 1
  • 5
  • 15
0
$data = ['a', 'b', 'c', 'd'];
$data = array_merge([''], $data);
unset($data[0]);

I have found that this will perform slightly better, than the accepted solution, on versions of PHP 7.1+.

Benchmark code:

$start = microtime(1);
for ($a = 0; $a < 10000; ++$a) {
    $data = ['a', 'b', 'c', 'd'];
    $data = array_merge([''], $data);
    unset($data[0]);
}
echo (microtime(1) - $start) . "\n";

$start = microtime(1);
for ($a = 0; $a < 10000; ++$a) {
    $data = ['a', 'b', 'c', 'd'];
    array_unshift($data, '');
    unset($data[0]);
}
echo (microtime(1) - $start) . "\n";

Scripts execution time (PHP 7.4):

0.0011248588562012 
0.0017051696777344 

And the difference of these benchmarks will increase as the number of array values increases.

arraksis
  • 31
  • 3
0

If you already have an array and want to reindex it to start from index X instead of 0, 1, 3...N then:

// Check if an array is filled by doing this check.
if (count($your_array) > 0) {
    // Let's say we want to start from index - 5.
    $your_array = [5 => $your_array[0], ...array_slice($your_array, 1)];
}

About spread operator "..."
https://www.php.net/manual/en/migration56.new-features.php#migration56.new-features.splat

P.S.

Real-world scenario/use-case, what I've met in work doing a task for a client:

I had one <div> that contains two <tables>. Each <table> contains markup for the days of the week. The first one has days from Monday to Thursday. The second one has days from Friday to Sunday. So, in my task, I had the variable represent a week in which each day had hours of open and close. I needed appropriately divide that week's variable into two.

<table>
    <?php for ($dayIndex = 0; $dayIndex < 4; $dayIndex++):  ?>
        <?php 
            $_timetable = array_slice($timetable, 0, 4);

            // $renderTimetableRow is an anonymous function
            // that contains a markup to be rendered, like
            // a html-component.
            $renderTimetableRow($_timetable, $dayIndex); 
        ?>
    <?php endfor; ?>
</table>

<table>
    <?php for($dayIndex = 4; $dayIndex < 7; $dayIndex++):  ?>
        <?php 
            if (count($_timetable = array_slice($timetable, 4, 7)) > 0) {
                $_timetable = [4 => $_timetable[0], ...array_slice($_timetable, 1)];
            }
        
            // $renderTimetableRow is an anonymous function
            // that contains a markup to be rendered, like
            // a html-component.
            $renderTimetableRow($_timetable, $dayIndex); 
        ?>
    <?php endfor; ?>
</table>
Gromax
  • 1
  • 1
-1
<?php
$home = ['hello','hii','bye','byee'];
$home = array_filter(array_merge(array(0), $home));
print_r($home);
// Ans
Array
(
    [1] => hello
    [2] => hii
    [3] => bye
    [4] => byee
);

?>
  • 2
    This unexplained answer does not perform as required. "_I want to re index the whole array such that the the first value key should be 1 instead of zero_" – mickmackusa Apr 10 '23 at 07:10
-3

try this

<?php
$stack = array('a', 'b', 'c', 'd');
$i= 1;
foreach($stack as $value){
    $stack2[$i] = $value;
    $i++;
}
$stack = stack2;
?>
Poonam Bhatt
  • 10,154
  • 16
  • 53
  • 72