Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the next numeric index of an existing array?

Tags:

arrays

php

I'm looking for a simple way to obtain the next numerical index of an array for a new element that would have been chosen by PHP as well.

Example 1:

$array = array();
$array[] = 'new index';

This would be 0 for this case.

Example 1a:

$array = array(100 => 'prefill 1');
unset($x[100]);
$x[] = 'new index';

This would be 101 for this case.

Example 2:

$array = array(-2 => 'prefill 1' );
$array[] = 'new index';

This would be 0 again for this case.

Example 3:

$array = array(-2 => 'prefill 1', 1 => 'prefill 2' );
$array[] = 'new index';

This would be 2 for this case.

I'd like now to know the next numerical key that PHP would have chosen as well for the new element in the array but w/o iterating over all the arrays values if possible.

I need this for a own array implementation via the SPL that should mimic PHP default behavior if a new element is added w/o specifying the offset.

Example 4:

$array = array(-2 => 'prefill 1', 'str-key-1' => 'prefill 2', 1 => 'prefill 3' , 'str-key-2' => 'prefill 4');
$array[] = 'new index';

This would be 2 for this case again.

Example 5:

$array = array(-2 => 'prefill-1', 'str-key-1' => 'prefill-2', 1 => 'prefill-3' , '5667 str-key-2' => 'prefill-4');
$array[] = 'new index';

This would be 2 for this case as well.

Update: I've added more examples to show some of the edge cases.

like image 203
hakre Avatar asked Sep 13 '10 08:09

hakre


3 Answers

Method 1:

Use end to advance the array to the end. The get the key of that item. Finally, add 1 to it to get the index of next item. Like this:

$array [ ] = 'I';
$array [4] = 'Like';
$array [ ] = 'Turtles';

end($array);
$last = key($array);
$nextindex = $last + 1;

echo $nextindex;

This outputs:

6

This method fails in cases where last index is not greatest or a string (as pointed out in comments). So, there is this better method 2 in those cases.


Method 2:

This method works on negative and string based indexes:
You can get array_keys and do a max of it, then +1 . Like this:

 $array = array(-2 => 'prefill 1', 'str-key-1' => 'prefill 2', 1 => 'prefill 3' , 'str-key-2' => 'prefill 4');
 echo max(array_keys($array)) + 1;

This outputs correctly:

2

like image 141
shamittomar Avatar answered Oct 29 '22 03:10

shamittomar


A zend hash table has an element nNextFreeElement, which contains the number you are looking for. Every time an item is added, this field is updated to be the maximum of itself and the index + 1.

ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC)
{
    ...
    if ((long)h >= (long)ht->nNextFreeElement) {
            ht->nNextFreeElement = h < LONG_MAX ? h + 1 : LONG_MAX;
    }
    ...
 }
like image 36
Sjoerd Avatar answered Oct 29 '22 02:10

Sjoerd


I don't think the necessary information is exposed to PHP scripts. Consider:

<?php
    $x = array(100 => 'foo');
    unset($x[100]);
    $x[] = 'bar';
    var_dump($x);
?>

array(1) {
  [101]=>
  string(3) "bar"
}

There would be no way to know that 101 is the next integer given that seemingly empty array, until after adding the item.

If you are building your own array class from scratch, then you could keep track of the next index via a private member variable.

like image 27
Matthew Avatar answered Oct 29 '22 02:10

Matthew