tags:

views:

81

answers:

5
A: 

if your array use only numeric key and without hole, you can do $next_id = count($your_array)

if there is holes, ou can try

$keys = array_keys($your_array);
rsort($keys);
$next_id = empty($keys)?0:($keys[0]+1);
mathroc
rsort returns a bool, doesn't it?
middus
correct fixed :)
mathroc
+1  A: 

I can't really think up anything except sorting the array and going through it, looking for holes.

Maybe something like:

sort($array);
$next_available = array_shift($array);
foreach($array as $_k) {
    ++$next_available;
    if($_k > $next_available) {
        break;
    }
}
echo "Next available index: {$next_available}";
Atli
+1  A: 

I don't believe this is less messy than some loop, but here goes my contrived example:

sort( $array );
$range = range( reset( $array ), end( $array ) );
$diff = array_diff( $range, $array );
$result = null != ( $result = array_shift( $diff ) ) ? $result : end( $array ) + 1;
fireeyedboy
Can't believe you beat me by 31 seconds, I knew I shouldn't have bothered fetching the links lol.
Andy E
Haha, I know the feeling but all too well. ;-) Yours is a bit cleaner though. Although stricts standards don't allow you to pass arguments to `array_diff` like that.
fireeyedboy
@fireeyedboy: as I said in my answer, my PHP skills are a bit rusty so I don't do much with strict standards. I write some PHP maybe once every couple of months or so :-)
Andy E
+5  A: 

My PHP skills are a bit rusty, but couldn't you use range and array_diff:

$missing = array_diff(range(1, end($myArray)+ 1), $myArray);
echo $missing[0];

Updated with Tatu Ulmanen's corrections (i told ya my PHP was rusty ;-))

Andy E
+1 That's the kind of answer I originally wanted to give, didn't know about `range` though and creating the sequence array oneself would indeed be messy. However, you probably have to use `array_keys($myArray)` as the first arguement and take into account the possibility that there is no hole in the array.
middus
This is just the kind of solution I'm looking for. This should work with one correction: `end($myArray)` instead of `count($myArray)`, as the count might be less than the largest value in the array.
Tatu Ulmanen
@Tatu: Good point, fixed :-)
Andy E
Whoops, forget about the `array_keys()`. I think I misread the question into something else.
middus
+1, was my thought too
stereofrog
@Andy, this actually needed some modifications to get it working; first of all, the "full" array has to be first, and the range should extend to `end($myArray) + 1` to allow it to return the next ID if there are no holes in `$myArray`. So the correct version would look like this: `array_diff(range(1, end($myArray)+ 1), $myArray);`
Tatu Ulmanen
@Tatu: Glad you got it working in the end. I didn't realize the range would have to go in as the first parameter. I've updated the post again :-)
Andy E
+1  A: 

This is a bit of magic, but does the trick:

$values = array_values($id_array);
$values[] = max($values) + 1;
$combined = array_values(array_flip($values) + array_keys($values));
$missing = isset($combined[count($values) + 1])
    ? $combined[count($values) + 1]
    : end($values);

The advantage of this is that it's considerably fast. The problem with using range() would be that single large key in a small array would make array_diff() very slow. In addition, this will return the next key if there are no gaps in the IDs (or you could change final end($values) to false, if that's what you would prefer).

Despite the cleverness, it's still slower than simply iterating through the array. But array_diff() (even without range()) would be much, much slower.

Rithiur