views:

2553

answers:

8

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] => 
    )

)
+2  A: 

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.

Gumbo
+2  A: 

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
Jason Cohen
Any answer to this problem should not need a loop. The key part of the answer is using `array_values()` to get a 0-based array and then making some adjustment to that result if a 1-based array is *really* required.
grantwparks
+1  A: 

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 ) 

?>
Greg
+2  A: 

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 ) );
}
Peter Bailey
+6  A: 

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:

Andrew Moore
+1  A: 
$tmp = array();
foreach (array_values($array) as $key => $value) {
    $tmp[$key+1] = $value;
}
$array = $tmp;
Tom Haigh
+1  A: 

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.

Michael Trausch
A: 

Sorting is just a sort(), reindexing seems a bit silly but if it's 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 )

?>
monowerker